compuknow Ответов: 1

Scanf() терпит неудачу после функции getchar ().


Я пытаюсь написать программу, в которой я мог бы динамически увеличивать размер указателя символов по мере того, как пользователь вводит каждый символ в консоль. Вот программа, в которой я пытаюсь использовать эту концепцию: (динамически выделенная строка)

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>

struct Structure
{
	char *buf;
	int intvar1, intvar2;
};

char *getdt()
{
	char *chr = (char*)malloc(1);
	int i = 0;
	char ch = getchar();
	while (ch != '\n')
	{
		chr[i] = ch;
		ch = getchar();
		chr = (char *)realloc(chr, (++i) + 1);
	}
	chr[i] = '\0';

	return chr;
}

void main()
{

	int elmts = 0, i = 0;
	Structure * strt;
	scanf("%d", &elmts);

	strt = (Structure*)malloc(sizeof(Structure)*elmts);

	for (i = 0; i < elmts; i++)
	{
		strt[i].buf = getdt();
		scanf("%d", &strt[i].intvar1);
		scanf("%d", &strt[i].intvar2);

	}

	for (i = 0; i < elmts; i++)
	{
		printf("%s %d %f", strt[i].buf, strt[i].intvar1, strt[i].intvar2);
	}


	free(strt);
	getch();

}


[Этот getdt() функция должна получить строку от пользователя.]

Единственная проблема заключается в следующем фрагменте:
strt[i].buf = getdt();
		scanf("%d", &strt[i].intvar1);
		scanf("%d", &strt[i].intvar2);

где я могу правильно извлечь строку strt[i].buf = getdt(), но последовательный scanf () пропускается и переходит непосредственно к нижнему циклу for.

После некоторых исследований я подозреваю, что виновником будет комбинация getchar() и scanf (). Но я действительно не понимаю, что вызывает неисправность.

Можно ли предложить какие-либо поправки ?

Что я уже пробовал:

Это то, что я пробовал:
for (i = 0; i < n; i++)
{
strt[i].buf = getdt();
char tmp[10],tmp1[10], *tp,*tq;
getss(tmp);
strt[i].intvar1 = strtol(tmp,&tp,10);
gets(tmp1)
strt[i].intvar2 = strtol(tmp1,&tq,10)
}

Эти усилия были просто напрасны.

Rick York

Я думаю, что ответ Ричарда попал точно в цель. Если вы не хотите использовать gets, то можете написать свой собственный, который принимает столько символов, сколько вводится. Я думаю, что было бы проще просто передать действительно большую строку, скажем 128 или 256 символов, потому что маловероятно, что пользователь введет такую большую строку для этой цели.

1 Ответов

Рейтинг:
1

Richard MacCutchan

Зачем усложнять себе жизнь? Воспользуйся получает, _getws[^] чтобы прочитать строку. Это общая проблема с scanf, он не очень хорошо сочетается с другими консольными вызовами ввода символов; gets следует избегать этой проблемы, так как она очищает входной буфер.


compuknow

Можно ли использовать gets, если размер массива char (или указателя в данном случае) известен только во время выполнения, т. е. только тогда, когда пользователь вводит строку ?

Richard MacCutchan

Документация все объясняет.

compuknow

В документе приведен пример массивов фиксированного размера. например, " char line[21]", но у меня есть указатель char, значение которого известно только тогда, когда пользователь вводит строку.

Richard MacCutchan

Затем используйте getchar, как вы это сделали, но убедитесь, что вы очистили входной буфер, чтобы scanf работал. Видеть http://c-faq.com/stdio/stdinflush2.html К сожалению, scanf не является особенно дружественной функцией, поэтому вам придется кодировать ее, чтобы получить желаемый результат.