#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_STRING 20
char *getFirstName() {
char firstName[MAX_STRING];
printf("Please enter your first name: ");
gets(firstName);
return (firstName);
}
char *getLastName() {
char lastName[MAX_STRING];
printf("Please enter your last name: ");
gets(lastName);
return (lastName);
}
char *getNickName() {
char nickName[MAX_STRING];
printf("Please enter your nick name: ");
gets(nickName);
return (nickName);
}
char *getCompleteName(const char *firstName,
const char *lastName,
const char *nickName) {
char *completeName;
sprintf(completeName, "%s \"%s\" %s", firstName, nickName, lastName);
return (completeName);
}
int main() {
char *firstName;
char *lastName;
char *nickName;
char *completeName;
firstName = getFirstName();
lastName = getLastName();
nickName = getNickName();
completeName = getCompleteName(firstName, lastName, nickName);
printf("Hello %s.\n", completeName);
return (EXIT_SUCCESS);
}
代码有什么问题。它总是在所有三个变量firstName
,lastName
和nickName
中打印昵称。
输出:]
它必须显示完整的名称。我认为错误在getCompleteName
函数中。
我建议使用char
数组并将它们作为参数传递给您的函数。如果char firstName[MAX_STRING];
终止,你本地数组getFirstName
超出范围。在getFirstName
终止并且指向变量的指针未定义的行为之后,此变量不再可访问。
#include <stdio.h>
#define MAX_STRING 10
void getFirstName( char *firstName )
{
printf("Please enter your first name: ");
fflush( stdout );
fgets( firstName, MAX_STRING, stdin );
}
void getLastName( char *lastName )
{
printf("Please enter your last name: ");
fflush( stdout );
fgets( lastName, MAX_STRING, stdin );
}
void getNickName( char *nickName )
{
printf("Please enter your nick name: ");
fflush( stdout );
fgets( nickName, MAX_STRING, stdin );
}
void getCompleteName (
char* completeName,
const char* firstName,
const char* lastName,
const char* nickName)
{
sprintf(completeName,"%s \"%s\" %s",firstName,nickName,lastName);
}
int main ()
{
char firstName[MAX_STRING];
char lastName[MAX_STRING];
char nickName[MAX_STRING];
char completeName[MAX_STRING*3+10];
getFirstName( firstName );
getLastName( lastName );
getNickName( nickName );
getCompleteName( completeName, firstName, lastName, nickName );
printf("Hello %s.\n",completeName);
return(EXIT_SUCCESS);
}
除了这个使用fgets
而不是gets
,因为qazxsw poi检查要读取的最大字符数(包括最终的空字符)请参阅fgets
在函数How to read from stdin with fgets()?中,在将内容组合到其中之前,必须为getCompleteName
分配内存:
completeName
笔记:
char *getCompleteName(const char *firstName,
const char *lastName,
const char *nickName)
{
size_t size = strlen(firstName) + strlen(lastName) + strlen(nickName) + 5;
char *completeName = malloc(size);
if (completeName) {
snprintf(completeName, size, "%s \"%s\" %s", firstName, nickName, lastName);
}
return completeName;
}
,它不能安全使用。使用gets()
并去除拖尾换行符。fgets()
completeName指向哪里?由于使用了不确定的值,这会调用未定义的行为。
你应该提供静态存储,例如同
char* completeName;
sprintf(completeName,"%s \"%s\" %s",firstName,nickName,lastName);
下一个问题是自动变量,例如函数返回时超出范围。您应该使数组静态以避免这种情况。
1)你不能在堆栈上使用数组 - 也许这可能会更好
static char completeName[128];
2)使用它
void getDetail(const char * const prompt, char *detail, int maxSize)
{
printf("%s:", prompt);
fflush(stdout); // Gives the user a chance to set it
if (fgets(detail, maxSize, stdin) == NULL) {
detail[0] = 0; // EOF - Empty string
}
else
{
// Strip off new line
size_t l = strlen(detail);
if (detail[l - 1] == '\n') detail[l - 1] = 0;
}
}
3)现在制作完整的名称
char firstName[MAX_SIZE];
getDetail("Please enter you first name", firstName, MAX_SIZE);
... ditto for the others
...如果你希望把它放入一个函数传递到它的数组。但在这个例子中似乎并不值得
4)打印完整名称
char completeName{MAX_SIZE * 3 + 10]; // Cannot be bothered to work out the exta but that will be enough
sprintf(completeName,"%s \"%s\" %s",firstName,nickName,lastName);
指针变量printf("Complete name is :%s\n", completeName);
未初始化,导致C标准调用未识别的行为。任何事情都可能发生。
您还尝试从函数中返回数组。它们被转换为指向每个数组中第一个元素的指针,并返回该指针。但由于数组是一个局部变量,所谓的“存储类自动”,它会在函数返回时消失。 Rhe记忆可以重复用于其他事情,但指针仍然指向内存中的那个位置。同样,行为未定义。
使用char和fgets数组而不是gets。顺便说一下,你的初始代码在Ubuntu 15.10和gcc(Ubuntu 5.2.1-22ubuntu2)5.2.1 20151010上产生了分段错误。
SK