char* readScores(int* actualCount) {
char* stringArray = (char*)malloc(100*sizeof(char));
for(int i = 0; i <= 13; i++) {
*actualCount = *actualCount + 1;
scanf("%s", &stringArray[i]);
printf("stringArray = %s when i = %d\t actualCount = %d\n", &stringArray[i], i, *actualCount);
}
printf("Finished!");
return stringArray;
}
使用这段代码,我循环遍历一个带有一些单词的.txt文件。当我运行这段代码时,我发现我确实在数组中的正确位置得到了正确的单词,但是一旦循环到达文件的末尾,程序就会给我一个段错误。我猜这是因为循环正在达到EOF值并抛出错误,但我无法弄清楚如何修复它。以下是结果的屏幕截图:http://i.imgur.com/kduzBnp.png
感谢您的帮助!
修改
我将代码更改为:
while(scanf("%s", &stringArray) != EOF) {
*actualCount = *actualCount + 1;
printf("stringArray = %s when actualCount = %d\n", &stringArray, *actualCount);
}
但是,我仍然遇到具有相同输出值的段错误。所以我知道它正在正确读取文件,我只是不知道为什么它会在最后停止并抛出错误。
答案 0 :(得分:2)
只要scanf
成功从标准输入中读取单词,您就希望继续循环。
因此循环的终止条件应使用scanf
返回的结果。
scanf
返回成功读取的项目数。如果成功阅读了某个单词,则会返回1
,否则会返回0
或EOF
。
但您的代码还存在其他一些问题。
char* stringArray = (char*)malloc(100*sizeof(char));
这不会为100个字符串分配空间,甚至不会为100个指向字符串的指针分配空间。它仅为100 char
s的单个数组分配空间。最好写成:
char *stringArray = malloc(100);
投放malloc
的结果是不必要的,可以掩盖错误,sizeof(char)
按定义为1。
你的for
循环将连续的单词读入内存,从分配数组中的位置0开始,然后是位置1,然后是位置2等,每个读取覆盖前一个的部分。
此外,具有scanf
格式的"%s"
本质上是不安全的,因为它将读取与用户类型(或来自stdin
所连接的任何字符)一样多的字符,而不管目标数组的大小。
使用fgets()
读取文本行更安全,然后可能sscanf
来解析输入(尽管sscanf
有一些问题)。
如果你想存储多个字符串,你需要为它们分配空间。我不确定你要提供什么来提供更具体的建议。
答案 1 :(得分:1)
scanf()
通常是一个很糟糕的功能,但是,从评论中收集到的,如果你坚持使用它,下面的代码会做我想你想做的事情,在这里:
#include <stdio.h>
#include <stdlib.h>
char ** create_string_array(const size_t num_strings, const size_t maxlen) {
char ** new_array = malloc(num_strings * sizeof(*new_array));
if ( new_array == NULL ) {
perror("Couldn't allocate memory for string array.");
exit(EXIT_FAILURE);
}
for ( size_t i = 0; i < num_strings; ++i ) {
new_array[i] = malloc(maxlen);
if ( new_array[i] == NULL ) {
perror("Couldn't allocate memory for string.");
exit(EXIT_FAILURE);
}
}
return new_array;
}
void free_string_array(char ** array, const size_t num_strings) {
for ( size_t i = 0; i < num_strings; ++i ) {
free(array[i]);
}
free(array);
}
char ** readScores(int* actualCount) {
char ** stringArray = create_string_array(14, 100);
for (int i = 0; i < 14; ++i) {
int status = scanf("%s", stringArray[i]);
if ( status == 0 || status == EOF ) {
break;
}
*actualCount = *actualCount + 1;
printf("stringArray = %s when i = %d\t actualCount = %d\n",
stringArray[i], i, *actualCount);
}
printf("Finished!\n");
return stringArray;
}
int main(void) {
int num_strings = 0;
char ** stringArray = readScores(&num_strings);
printf("There were %d strings read. They are:\n", num_strings);
for ( int i = 0; i < num_strings; ++i ) {
printf("%2d: %s\n", i + 1, stringArray[i]);
}
free_string_array(stringArray, num_strings);
return EXIT_SUCCESS;
}
并使用合适的数据文件输出:
paul@local:~/src/c/scratch$ cat data_file
Twas
brillig
and
the
slithy
toves
did
gyre
and
gimble
in
the
wabe
paul@local:~/src/c/scratch$ cat data_file | ./strcount
stringArray = Twas when i = 0 actualCount = 1
stringArray = brillig when i = 1 actualCount = 2
stringArray = and when i = 2 actualCount = 3
stringArray = the when i = 3 actualCount = 4
stringArray = slithy when i = 4 actualCount = 5
stringArray = toves when i = 5 actualCount = 6
stringArray = did when i = 6 actualCount = 7
stringArray = gyre when i = 7 actualCount = 8
stringArray = and when i = 8 actualCount = 9
stringArray = gimble when i = 9 actualCount = 10
stringArray = in when i = 10 actualCount = 11
stringArray = the when i = 11 actualCount = 12
stringArray = wabe when i = 12 actualCount = 13
Finished!
There were 13 strings read. They are:
1: Twas
2: brillig
3: and
4: the
5: slithy
6: toves
7: did
8: gyre
9: and
10: gimble
11: in
12: the
13: wabe
paul@local:~/src/c/scratch$
Keith已经指出了你所遇到的基本错误,即如果你需要一个动态的字符串数组,那么你需要malloc()
内存来获得指向char *
的指针数组,然后每个一个,malloc()
内存用于字符串本身,原始代码不会执行此操作,您需要检查scanf()
对0
和EOF
的回复。
答案 2 :(得分:0)
您可以使用while循环替换for循环。
while (fgets(buffer, buffer_size, fp)) {
// do something with buffer
}
if (ferror(fp)) {
// handle the error, usually exit or return
} else {
// continue execution
}
答案 3 :(得分:0)
char* readScores(int* actualCount) {
char* stringArray = (char*)malloc(100*sizeof(char));
int i=0, len;
while(scanf("%s%n%*c", &stringArray[i], &len)==1){
printf("stringArray = %s when i = %d\t actualCount = %d\n", &stringArray[i], i, ++*actualCount);
i += len + 1;
}
printf("Finished!");
return stringArray;
}
答案 4 :(得分:-1)
您提供的代码没有问题。我自己和Windows上的MSVC都没有遇到任何麻烦。这是它的样子:
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
int main( )
{
FILE * asd;
char* stringArray = calloc( 100, sizeof(char) );
int actualCount = 0;
freopen_s( &asd, "wsx.txt", "w+", stdin );
fprintf_s( stdin, "this is a test this is only a test this also is a test" );
rewind( stdin );
for ( int i = 0; i <= 13; i++ ) {
actualCount = actualCount + 1;
scanf_s( "%s", &stringArray[i], 100 - i );
printf_s( "stringArray = %s when i = %d\t actualCount = %d\n", &stringArray[i], i, actualCount );
}
printf( "Finished!" );
Sleep( 5000 );
return 0;
}
输出正如您所期望的那样,没有错误......所以我的答案是您遇到的问题是由于您编写的代码以外的其他原因。