我有一个小示例程序来说明我的问题:我有一个简单的文本文件,其中有三个单词(每个都在一个新行中),fscanf读取,分配给一个临时变量,然后转移到一个字符串数组。然而,这些值似乎没有转移到数组。 另外,当我从while循环中的第二个printf中删除注释时,我得到一个seg错误。
我对C很新,所以现在才学习这些功能的用法!在此先感谢您的帮助!
#include <stdio.h>
#include <string.h>
int main (int argc, char* argv[])
{
char* words[15];
char tmp[45];
int i = 0;
FILE* fp = fopen("small", "r");
while (fscanf(fp, "%s", tmp) == 1)
{
printf("%s\n", tmp);
words[i] = tmp;
i++;
//printf("%s ", words[i]);
}
printf("\n");
printf("Words 0 = %s\n", words[0]);
printf("Words 2 = %s\n", words[1]);
printf("Words 3 = %s\n", words[2]);
fclose(fp);
}
输出
pears
apples
zipper
Words 0 = zipper
Words 2 = zipper
Words 3 = zipper
答案 0 :(得分:4)
在您的代码中,words[i] = tmp;
不是存储每个words
数组输入的方式。这只会将tmp
数组的基地址存储到每个words[i]
中,之后,在打印时,它实际上会在每次迭代时打印tmp
的最新内容。
如果您想将tmp
数组的内容放入每个words[i]
,您需要
words[i]
分配内存并使用strcpy()
strdup()
并将其分配给words[i]
。在任何一种情况下,您必须在退出前free()
分配的记忆。
答案 1 :(得分:1)
过去我遇到过同样的问题。
问题在于,当您从文件中读取时,该单词将保留在缓冲区中,然后将其存储到变量temp。
问题在于,当您阅读下一个单词时,缓冲区的内容会发生变化。这也会影响之前的通话!
所以你读了&#34; pears&#34;,你打印&#34; pears&#34;和单词[0] =&#34;梨子&#34;
然后你读了&#34;苹果&#34;,你打印苹果和单词[1] =&#34;苹果&#34;。但是还有单词[0] =&#34;苹果&#34;现在!!
等等......
你需要做的是在阅读文件之前,为每个单词[i]分配内存和malloc,并使其等于&#34;&#34;。
e.g。 words[0] = ""
等。
然后当你开始阅读文件时,你应该对temp和words [i]使用strcpy()函数。这将解决您的问题。
我试着尽可能简单地回答这个问题,因为过去这个问题困扰着我,让我很困惑。
答案 2 :(得分:0)
您的代码的第一个重要问题是此行
char* words[15];
它为您提供了15个char指针(char*
)的数组。这是不与15个字符串的数组相同。没有用于存储字符串的内存。
要获取用于存储字符串的内存,您可以执行以下操作:
char words[15][45];
// ^ ^^
// no * memory for each of the 15 strings
现在你有15个字符串的内存。每个字符串最多可以包含44个字符。
通过此更改,您不需要tmp
变量 - 只需直接阅读words
即可。类似的东西:
#include <stdio.h>
#include <string.h>
int main (int argc, char* argv[])
{
char words[15][45];
int i = 0;
FILE* fp = fopen("small", "r");
if (!fp)
{
printf("no such file\n");
return 0;
}
while ((i < 15) && (fscanf(fp, "%44s", words[i]) == 1))
{ // ^^^^^^^^ is the same as &words[i][0]
i++;
}
printf("\n");
int t;
for (t = 0; t < i; ++t)
{
printf("Words %d = %s\n", t, words[t]);
}
fclose(fp);
return 0;
}
添加了一些其他重要更改:
1)fopen
之后你必须检查NULL
2)对于带有%s的scanf,总是给出最大尺寸(即%44s),这样就不会有缓冲区溢出
3)确保在读取15个字符串时停止while
(以防止缓冲区溢出)
4)只打印您在
中读取的字符串最后,我将return 0
添加到main