我真的很难过这个。
我在c中编写了一个简单的程序来从用户键盘输入中检索名字,姓氏和YOB(出生年份)(我还没有将年龄解析为整数)并且我设置了一个最大值输入的字符数。
但每当我允许字段的最大字符数为50或更大时,返回值始终为空。
这是代码(60行),输出如下。导致故障的功能是倒数第二个函数getInputNoNewLine:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void flushBuffer();
char *getInput(int max, char message[]);
char *getInputNoNewline(int max, char message[]);
typedef struct Person {
char *firstName;
char *lastName;
int yob;
} Person;
void flushBuffer() {
int ch;
while ((ch = getchar()) != '\n' && ch != EOF); //flush the input buffer
}
char *getInput(int max, char message[]) {
char in[max];
char *input;
do {
printf("%s", message);
input = fgets(in, max + 2, stdin); //max + 2 accounts for characters fgets adds
if (input[strlen(input)-1] != '\n') {
printf("Sorry, maximum %d characters\n", (max));
flushBuffer();
}
} while (input[(strlen(input)-1)] != '\n');
printf("input: %s", input); //debug
return input;
}
//OFFENDING FUNCTION
char *getInputNoNewline(int max, char message[]) {
char *input;
input = getInput(max, message);
printf("raw input : %s", input); //debug
if (input[strlen(input) - 1] == '\n') { //strip new line character
input[strlen(input) - 1] = '\0';
}
printf("final input: '%s'\n", input); //debug
return input;
}
int main(int argc, char *argv[]) {
int numPlayers = 3;
char *intIn;
int i = 0;
Person players[numPlayers];
printf("Hello world Game\n");
for (i = 0; i < numPlayers; ++i) {
players[i].firstName = getInputNoNewline(50, "What is your first name: "); //50 will return blank
players[i].lastName = getInputNoNewline(49, "What is your last name: "); //49 will return fine
intIn = getInputNoNewline(4, "What is your YOB: "); //TODO: convert number to integer with sscanf
printf("-----------------------------------\n");
}
printf("Finished\n");
return 0;
}
这是输出,你可以看到jim的第一个输入是从fgets接收的,但返回值是空白的(原始输入:)。如果我要将最大值从50减少到49,根据姓氏字段的情况,它完全正常。有什么想法吗?
Hello world Game
What is your first name: jim
input: jim
raw input : final input: ''
What is your last name: smith
input: smith
raw input : smith
final input: 'smith'
What is your YOB: 1984
input: 1984
raw input : 1984
final input: '1984'
-----------------------------------
答案 0 :(得分:3)
您的代码有未定义的行为 您正在返回指向本地分配的数组的指针。
char *getInput(int max, char message[])
{
char in[max];
....
....
return input;
}
in
是函数的本地数组,只保证在函数范围{``}
之前是活动的。为了能够访问超出函数范围的此数组的内容,您需要通过以下方式增加数组的生命周期:
malloc
或static
或全球如果使用malloc
,请不要忘记在使用后通过调用free
取消分配数组,否则最终会导致内存泄漏。
答案 1 :(得分:2)
由于您将in
分配为50个字符长,并且您允许读取52个字符,因此您将遇到麻烦!你想用
static char* in;
if(in!=NULL) free(in);
in = (char*)malloc(max + 2);
这解决了Alok引发的问题(关于函数返回时局部范围指针未被定义),以及您的函数允许fgets
将max+2
个字符写入缓冲区{{1 }}
答案 2 :(得分:0)
您有许多内存管理问题。 fgets调用正在请求崩溃,因为你传入的长度比分配的内存长2个字节。您还将返回从fgets返回的char *并将其视为已分配的内存。
您应该复制从fgets返回的缓冲区并将其存储在Person结构中。
真的,我认为你应该检查基本的C内存分配和销毁。