这是一个我不明白的问题 - 我在main中使用fgets()
并且它有效。我在一个函数中以完全相同的方式使用它(我认为)并且我得到一个错误[Segmentation fault core dumped - 退出代码139)。
此代码基于Ivor Horton" Beginning C" (这是一块古老的瓷砖,但我只是想从中学习基础知识。)
我的程序如下。我正在使用Geany工作* nix(基本上,使用GCC编译)。您可以看到fgets
在main中工作(输出是您输入的字符串)。但它在函数str_in()
中不起作用。它到第二个printf()
语句输入一个字符串,没有进一步。请注意,在本书中,Horton使用gets()
。我想在这里实现一个更安全的字符串输入函数,但没有快乐。
顺便说一下程序应该对存储在字符串指针数组中的字符串进行排序。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define MAX_NUM_STRINGS 50
int str_in(char **); /*Pointer to a string pointer*/
void str_sort(char *[], int n); /*Array of pointers to strings, number of strings in array*/
void str_out (char *[], int n); /*Array of pointers to strings, number of strings in array*/
int main(){
char *pS[MAX_NUM_STRINGS] = { NULL }; /*Array of pointers to strings stored in str_space*/
int numStrings = 0; /*Count of strings*/
char buffer[BUFSIZ];
printf("Enter a string\n");
fgets(buffer, BUFSIZ, stdin);
printf("%s", buffer);
printf("fgets works here\n\n");
/* get string input from user - a pointer to each string is saved in pS */
while ( str_in(&pS[numStrings]) && numStrings < MAX_NUM_STRINGS)
numStrings++;
if ( numStrings > 0 ){
str_sort(pS, numStrings);
str_out(pS, numStrings);
}
return 0;
}
int str_in(char** pString){
char buffer[BUFSIZ];
char *p;
printf ("Enter string:\n");
fgets(buffer, 60, stdin);
printf("fgets doesn't work here!!\n");
if( buffer != NULL ){
printf("here");
if ((p = strchr(buffer, '\n')) != NULL)
*p = '\0'; /*replace newline with null character*/
else
return FALSE;
if ( strlen(buffer) > 0 ){
strcpy(*pString, buffer);
return TRUE;
}
else
return FALSE; /*blank line - end of input*/
}
else
return FALSE;
}
void str_sort(char* pStrings[], int n){
/*sort strings by manipulating array of string pointers*/
char *temp;
int sorted = FALSE;
int i = 0;
while (!sorted){
sorted = TRUE;
for(i = 0; i < n - 1; i++){
temp = pStrings[i];
if ( strcmp(temp, pStrings[i+1]) > 1 ){
pStrings[i] = pStrings[i+1];
pStrings[i+1] = temp;
sorted = FALSE;
break;
}
}
}
}
void str_out(char* pStrings[], int n){
/*print strings to standard output. Free memory as each string is printed */
int i = 0;
printf("Sorted strings:\n");
for(i = 0; i < n; i++){
printf("%s", pStrings[i]);
free(pStrings[i]);
}
}
答案 0 :(得分:1)
你必须检查fgets的返回值,看看你是否已成功收到某些东西,如果没有,那么你永远不要将缓冲区用作字符串,因为你不是NUL终止缓冲区。
/* Checking for buffer != NULL is of no use */
/* as buffer will always be not NULL since */
/* since you have allocated it as char buffer[BUFSIZ] */
if (fgets(buffer, BUFSIZ, stdin) == NULL) {
/* buffer may not be a valid string */
}
所以,只要你输入函数,你就可以把缓冲区初始化为NUL字符串(声明完成后)
buffer[0] = 0; /* initialize to NUL string */
现在你可以在任何地方使用缓冲区作为字符串。
另请注意,如果BUFSIZ太大而不是几KB,那么由于堆栈溢出,您可能会遇到段错误。如果它们太大,你可以将缓冲区设为“静态字符”而不是“char”。
答案 1 :(得分:1)
细分错误不是由fgets()
引起的,而是由strcpy()
引起的:
strcpy(*pString, buffer);
您尝试写入*pString
,但您永远不会为此分配内存。 pS
中的main()
只是一个空指针数组。
另一件事是使用if( buffer != NULL )
进行测试,因为buffer
是数组而不是指针,所以永远不会成立。