我需要获取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()
。
答案 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
将读取的第一个字符,为空行。因此,它会确实读取所有行,但第一个行将被视为空。
这就是为什么您不似乎获得任何输出的原因,因为没有可打印的字符要打印。您得到的只是一个空行。