fgets()/ gets()问题,同时输入N个字符串。不在初始位置输入

时间:2018-10-27 10:45:37

标签: c multidimensional-array fgets c-strings gets

我需要获取n (用户输入)字符串的输入。为此,我首先定义一个二维数组char str [] []。
我使用for循环从用户处获取输入,并尝试了gets()fgets()两者。 在代码示例中,尽管我使用gets()。
但是它总是要为n-1个字符串输入输入,即比用户想要输入的输入少1个。
在进一步检查后,我发现程序没有输入第<0>个字符串(即初始字符串)的输入。

我的代码:

#include <stdio.h>
int main(void){
int i, n;

printf("how many string you want to enter: ");
scanf("%d", &n);

char str[n][60];

printf("start entering strings:\n ");

for(i=0;i<n;i++){     
    gets(str[i]);     //have used here fgets() also
}

puts(str[0]);         //no output for Oth string
return 0;
}

输出:

how many string you want to enter:

用户输入-3

how many string you want to enter: 3
start entering strings:

最终输出:

how many string you want to enter: 3
start entering strings:
 abc
bcd

在仅输入2个字符串并且没有为puts(str[0]);给出任何输出之后,这里的程序终止

尽管将scanf()用作scanf("%s", str[i]);可以很好地工作。
我想知道为什么使用gets()却不能使用fgets()

2 个答案:

答案 0 :(得分:4)

您需要消耗#include <iostream> #include <tuple> #include <vector> #include <cstddef> #include <limits> template<typename... Ts> using TupleVector = std::tuple<std::vector<Ts>...>; constexpr std::size_t size_t_max = std::numeric_limits<std::size_t>::max(); template<typename T, std::size_t N = size_t_max, typename FuncT> void for_all(T b, FuncT F) { constexpr std::size_t TupSize = std::tuple_size<T>::value; // Entry point: No 'N' given - default value. if constexpr (N == size_t_max) { for_all<T,TupSize-1>(b,F); // So call again with tuple size - 1 } else { // Actually do it. Loop through vector and call lambda, for (auto &i : std::get<TupSize-N-1>(b)) { F(i); } // If N == 0 escape, otherwise recurse. if constexpr (N > 0) { for_all<T,N-1>(b,F); // Recursively call with N - 1 } } } struct Dog { int age; }; struct Cat { int age; }; struct Pig { int age; }; struct Cow { int age; }; int main() { using farmvec = TupleVector<Dog, Cat, Pig, Cow>; farmvec animals; std::get<0>(animals).push_back(Dog()); std::get<0>(animals)[0].age=1; std::get<0>(animals).push_back(Dog()); std::get<0>(animals)[1].age=5; std::get<1>(animals).push_back(Cat()); std::get<1>(animals)[0].age=2; std::get<2>(animals).push_back(Pig()); std::get<2>(animals)[0].age=3; std::get<3>(animals).push_back(Cow()); std::get<3>(animals)[0].age=4; for_all<farmvec>(animals,[](auto a) { std::cout << "Age: " << a.age << std::endl; }); return 0; } 留下的剩余缓冲区:

scanf

您可以使用scanf("%d", &n); char str[n][60]; int c; while ((c = fgetc(stdin)) != '\n' && c != EOF); printf("start entering strings:\n "); fgets而非strtol来避免丑陋的冲洗循环:

scanf

答案 1 :(得分:2)

问题不是fgets(或gets)。问题是您之前致电scanf

Enter 键结束数字输入时,该 Enter 键将作为换行符添加到输入缓冲区。因此,scanf读取数字后,输入缓冲区中剩下的下一个字符将是该换行符。这是fgets将读取的第一个字符,为空行。因此,它会确实读取所有行,但第一个行将被视为

这就是为什么您不似乎获得任何输出的原因,因为没有可打印的字符要打印。您得到的只是一个空行。