我在C中读取空字符串时遇到问题。我想从以下内容中读取字符串 -
但是当我使用gets()
时,它不会将(empty)
视为字符串[2]。它将'cat'读作字符串[2]。那我怎么解决这个问题呢?
char str1[15002][12];
char str2[15002][12];
char s[25];
map<string,int> Map;
int main()
{
int ncase, i, j, n1, n2, count, Case;
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&ncase);
Case = 1;
while(ncase > 0)
{
Map.clear();
//this is the necessery part
scanf("%d %d\n",&n1,&n2);
count = 0;
printf("n1=%d n2=%d\n",n1,n2);
for(i = 0; i < n1; i++)
{
gets(str1[i]);
}
for(i = 0; i < n2; i++)
{
gets(str2[i]);
}
//end of reading input
for(i = 0; i < n1; i++)
{
for(j = 0; j < n2; j++)
{
strcpy(s,str1[i]);
strcat(s,str2[j]);
if(Map[s] == 0){
count += 1;
Map[s] = 1;
}
}
}
printf("Case %d: %d\n", Case, count);
Case++;
ncase--;
}
return 0;
}
并且输入看起来像
我在这里给出了代码。输入可能类似于
line1>1
line2>3 3
line3>(empty line)
line4>a
line5>b
line6>c
line7>(empty)
line8>b
我希望
str1[0]=(empty).
str1[1]=a;
str1[2]=b;
和
str2[0]=c;
str2[1]=(empty);
str2[2]=b;
好的,最后我发现了问题。这是行
printf("n1=%d n2=%d\n",n1,n2);
在gets()
输入时会产生问题。而不是使用整数n1
,n2
获取换行符,然后我将换行符作为("%c",&ch
),然后一切正常。
感谢所有回答我的人。
答案 0 :(得分:3)
可能是,字符串包含 \r\n\0
(或\n\r\0
- 永远不会记住哪个是第一个。 \r\n
是Windows上的换行符,\0
是字符串的终止字符。
通常,如果字符串的第一个字符是\r
或\n
,则会读取一个空字符串。 FWIW这应该适用于所有平台:
char* string;
// initialize string and read something into it
if (strlen(string) == 0 || string[0] == `\r` || string[0] == `\n`)
// string is empty
更新:您提到您使用gets
,并从文件中读取。但是,对于后者,你需要fgets
,所以这里有一些混乱。请注意,fgets
包含返回的字符串中的尾随换行符,而gets
则不包含。{/ 1>
Update3:您从文件中读取的方式确实很糟糕。你重新打开标准输入来读取文件 - 为什么???标准做法是fopen
该文件,然后使用fscanf
和fgets
从中读取。
Update2:愚蠢的我们(和聪明的@Salil :-)。你说
它将'cat'视为
string[3]
由于C数组从0开始索引, string[3]
包含第4行读取!第三行存储在string[2]
中 - 我打赌它将包含您要查找的空字符串。
答案 1 :(得分:2)
此代码的输出:
#include <cstdio>
int main ()
{
int i = 0;
char string [256];
while (gets(string)) {
++i;
}
printf("%d\n", i);
return 0;
}
对于此输入
a
b
d
是
4
这意味着,gets()会正确读取所有行,这反过来意味着必须搞砸你的代码。发布在这里。
答案 2 :(得分:2)
首先,不要使用获取 !!!!!它是buffer overflow vulnerability,因为您无法指定目标缓冲区的大小,因此gets()可以轻松地超出缓冲区。相反,请使用fgets()或getchar()。
由于您使用的是map&lt; string,int&gt;,因此很明显您实际上正在使用C ++代码。在这种情况下,更好的方法是使用C ++ iostreams库作为输入和输出。
现在我已经完成了我的咆哮,问题是这个......得到 - 再次,你永远不应该使用 - 根据规范,将读取直到换行,并且“任何&lt ;新行&gt;将被丢弃“。函数fgets()会将换行符复制到目标缓冲区中,为您提供所需的行为。
答案 3 :(得分:0)
如果没有字符串,您希望如何阅读它?
请给我们一段代码:)
==稍后编辑==
行:
“gets()从stdin读取一行到s指向的缓冲区,直到终止换行符或EOF,它替换为'\ 0'。”
所以基本上,如果你有:
char x [3];
得到(X);
然后此函数将使用'\ 0'
填充x [0]如果您阅读了联机帮助页,您会看到不建议使用。请改用fgets