#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a = 0, f = 0;
char ch[1];
char arr[1000];
while (f < 3) {
while (((*ch = getchar()) != 10))
{
scanf("%9s", &(arr[a]));
scanf("%9s", &(arr[a + 1]));
a += 2;
}
f++;
}
for (int i = 0; i < a; i++) {
printf("%sn", &arr[i]);
}
return 0;
}
这个代码应该收集输入,比如:
1 4 green 4 green 1 blue 2 blue 4 blue 5 blue 7 blue 5 red 7 red 1 violet 2 violet 4 violet 5 violet 7 violet
1
2 4 green 4 green 7 blue 1 red 2 red 4 red 5 red 7 red 1 violet 2 violet 4 violet 5 violet 7 violet
2
3 4 green 4 green 1 blue 2 blue 4 blue 7 blue 1 red 2 red 4 red 5 red 7 red 5 violet 7 violet
3
首先,有一些数字,然后是一个数字和一个单词。我不知道会有多少次,但我知道输入行的数量。我遇到的问题是,当在控制台中按下"回车"之前,输入行的末尾有一个空格时,程序会一直等待更多的输入。我不知道如何消除这种情况,尤其是在输入的最后一行,因为在最后一行的末尾放空格会导致程序永远等待用户键入内容。
让我们解开您的代码。
您正在使用getchar
来查找行的末尾,但它会吞下该字符。scanf
看不到;0123456789";CCD_ 3将吃掉0。您可以使用putchar
将其放回原处,但这完全没有必要。
scanf("%9s", &(arr[a]));
scanf("%9s", &(arr[a + 1]));
这是从输入中读取最多九个字符,并将其粘贴到字符串arr
中。然后,它从输入中再读取9个字符,并覆盖刚刚读取的8个字符。
要穿过它,我们假设这条线是";0123456789bcdefghijklmno";
- a:0
- stdin:";0123456789bcdefghijklmno">
- arr:";垃圾垃圾arr未初始化
getchar()
从stdin读取0。
- a:0
- stdin:";123456789bcdefghijklmno">
- arr:";垃圾垃圾
scanf("%9s", &(arr[a]))
从stdin读取123456789,并将其放入arr
,从a
开始,即0。
- a:0
- stdin:";abcdefghijklmno">
- arr:";123456789\0垃圾箱垃圾">
scanf("%9s", &(arr[a + 1]))
从stdin读取abcdefghi,并将其放入arr
,从a + 1
开始,这是1,覆盖了除了刚刚写入arr
的第一个字符之外的所有字符。
- a:0
- stdin:";jklmno">
- arr:";1abdedfghi \0百吉垃圾">
CCD_;1abdedfghi";。
char arr[1000]
为堆栈分配999个字符(加上一个空字节(的单个字符串的空间。我想你的意思是arr
是一个由1000个字符串组成的数组,每个字符串至少可以容纳9个字符加上空字节。这是char arr[1000][10]
。
scanf
有很多问题,尝试用getchar
逐行读取也是如此。相反,通常最好将带有fgets
的行读取到缓冲区中,并使用sscanf
或其他字符串解析函数解析该行。这避免了挂起等待输入或未知行大小的许多问题。
在这种情况下,使用strtok
(STRing TOKenizer(在空白处拆分行。strtok
的行为有点奇怪,因为它有自己的内部缓冲区。它也不分配新内存,而是返回原始行中的指针。空格被替换为空字节,所以看起来一次只得到一个令牌。使用strdup
将单词复制到数组中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
// A single line buffer to reuse.
// BUFSIZ is the size of the input buffer and a good size to choose.
char line[BUFSIZ];
// An array for 1000 strings.
// No memory is allocated for the strings themselves.
// We'll allocate as needed.
//
// Note: a real problem would not allocate a fixed size array.
// It would extend `words` as needed.
// You'll learn how to do that that later.
char *words[1000];
// Track how many words are in the words array.
int num_words = 0;
// Read at most 3 lines
for(int i = 0; i < 3; i++) {
// Read a line. Exit the loop early if there's no more lines.
if( !fgets(line, sizeof(line), stdin) ) {
break;
}
// Split the line on whitespace.
// fgets() does not strip newlines.
// We must include newline else it will be considered a word.
for(
char *word = strtok(line, " tn");
word;
word = strtok(NULL, " tn")
) {
// word is a pointer to memory inside line.
// The whitespace has been replaced by a null byte so we can
// read a single word. We could store that and save memory,
// but `line` will be reused to read the next line and
// the previous words will be overwritten.
// So we need to copy the word. `strdup` allocates just the
// right amount of memory.
words[num_words] = strdup(word);
num_words++;
}
}
for (int i = 0; i < num_words; i++) {
printf("%sn", words[i]);
}
return 0;
}
你应该能够根据你的具体任务调整基本代码,阅读一行行单词。