[英]C error reading characters of string. tring to print from string without success
我正在编写一个代码,我需要从“addReasons”function 中获取字符串并打印我在其他 function 中得到的所有字符串,如果有人能告诉我如何修复它,我会收到运行时错误,上面写着“读取字符串的字符时出错”会很有帮助。 谢谢你。
像这样调用 function :
addReasons(&proList);
addReasons(&conList);
printList(proList);
printList(conList);
编码:
typedef struct reasonList
{
char* listName;
char* reasons[MAX_LIST_LENGTH];
int numReasons;
} reasonList;
/*
Function will add a reason to the list
input: the list to add to and its name
output: none
*/
void addReason(reasonList* list)
{
int index = 0;
index = list->numReasons;
if (index < MAX_LIST_LENGTH)
{
printf("Enter a reason to add to list %s: ", list->listName);
fgets(&list->reasons[index], STR_LEN, stdin);
list->numReasons++;
}
}
/*
Function will print a list of reasons
input: the list
output: none
*/
void printList(reasonList list)
{
int i = 0;
printf("List %s\n", list.listName);
printf("---------\n");
for (i = 0; i < list.numReasons; i++)
{
printf("%s\n", list.reasons[i]);
}
}
fgets
需要一个char*
参数,但您传递了一个char**
参数。 编译器对此发出警告:
warning: incompatible pointer types passing 'char **' to parameter of type 'char *';
remove & [-Wincompatible-pointer-types]
fgets(&list->reasons[index], STR_LEN, stdin);
^~~~~~~~~~~~~~~~~~~~~
正确的方法是:
fgets(list->reasons[index], STR_LEN, stdin);
但是,现在这将使用未初始化的指针。 因此,您需要首先为该字符串分配 memory 并使用该地址初始化指针:
list->reasons[index] = malloc(STR_LEN);
fgets(list->reasons[index], STR_LEN, stdin);
您还需要在完成后free()
memory,否则如果您的程序长时间运行,您将泄漏 memory。
结构体reasonList
的数据成员reasons
是一个char *
类型的指针数组。
char* reasons[MAX_LIST_LENGTH];
所以这个fgets
调用的第一个参数
fgets(&list->reasons[index], STR_LEN, stdin);
具有char **
类型,而 function 需要char *
类型的参数。 所以这个调用会调用未定义的行为。
同样从提供的代码中,还不清楚这些指针(数组的元素)是否指向字符 arrays。 如果您没有动态分配指针将指向的字符 arrays 那么如果您甚至可以正确写入
fgets( list->reasons[index], STR_LEN, stdin);
然而,再次这样的调用将调用未定义的行为。
考虑到错误消息,您似乎确实忘记分配将由数组的元素(指针)指向的字符 arrays。
考虑到 function fgets
可以 append 换行符'\n'
到您应该删除的输入字符串。
例如,function 可以通过以下方式查看
int addReason( reasonList *list )
{
int success = list->numReasons < MAX_LIST_LENGTH;
if ( success )
{
list->reasons[list->numReasons] = malloc( STR_LEN );
success = list->reasons[list->numReasons] != NULL;
if ( success )
{
list->reasons[list->numReasons][0] = '\0';
printf( "Enter a reason to add to list %s: ", list->listName );
if ( fgets( list->reasons[list->numReasons], STR_LEN, stdin ) != NULL )
{
list->reasons[list->numReasons][ strcspn( list->reasons[list->numReasons], "\n" ) ] = '\0';
}
++list->numReasons;
}
}
return success;
}
问题的另一个原因可能与您应该使用字符串文字分配的数据成员listName
相关,或者您需要再次动态分配将由数据成员指向的字符数组。
顺便说一句,function printList
应该声明为
void printList( const reasonList *list );
代替
void printList( const reasonList *list );
因为创建一个 struct reasonList
类型的 object 的副本而不是传递一个指向它的指针是低效的。
这是一个演示程序。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LIST_LENGTH 10
#define STR_LEN 50
typedef struct reasonList
{
char* listName;
char* reasons[MAX_LIST_LENGTH];
int numReasons;
} reasonList;
int addReason( reasonList *list )
{
int success = list->numReasons < MAX_LIST_LENGTH;
if ( success )
{
list->reasons[list->numReasons] = malloc( STR_LEN );
success = list->reasons[list->numReasons] != NULL;
if ( success )
{
list->reasons[list->numReasons][0] = '\0';
printf( "Enter a reason to add to list %s: ", list->listName );
if ( fgets( list->reasons[list->numReasons], STR_LEN, stdin ) != NULL )
{
list->reasons[list->numReasons][ strcspn( list->reasons[list->numReasons], "\n" ) ] = '\0';
}
++list->numReasons;
}
}
return success;
}
void printList( const reasonList *list )
{
printf( "List %s\n", list->listName);
printf("---------\n");
for ( int i = 0; i < list->numReasons; i++ )
{
printf( "%s\n", list->reasons[i] );
}
}
int main(void)
{
reasonList list = { .listName = "List of reasons", .numReasons = 0 };
addReason( &list );
printList( &list );
return 0;
}
程序 output 可能看起来像
Enter a reason to add to list List of reasons: Unallocated memory
List List of reasons
---------
Unallocated memory
如果您出于动态原因分配 memory,那么您应该在退出程序之前释放所有已分配的 memory。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.