#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
函数中。
答案 0 :(得分:2)
在函数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()
并删除尾随换行符。答案 1 :(得分:1)
char* completeName;
sprintf(completeName,"%s \"%s\" %s",firstName,nickName,lastName);
completeName指向哪里?由于使用了不确定的值,这会调用未定义的行为。
您应该提供静态存储,例如与
static char completeName[128];
下一个问题是自动变量,例如函数返回时超出范围。您应该使数组静态以避免这种情况。
答案 2 :(得分:1)
1)你不能在堆栈上使用数组 - 也许这可能会更好
#include<stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include<signal.h>
#include<stdint.h>
#include<string.h>
#include<time.h>
void formatted_time(char* sender_name, char* receiver_name, char output[]);
void formatted_time( char* sender_name , char* receiver_name, char output[])
{
struct timeval tv;
time_t nowtime;
struct tm *nowtm;
char tmbuf[80];
gettimeofday(&tv, NULL);
nowtime = tv.tv_sec;
nowtm = localtime(&nowtime);
strftime(tmbuf,80 , "%Y-%m-%d %H:%M:%S",
nowtm);
sprintf(output, "%s: Time at %s is %s.", receiver_name, sender_name, tmbuf);
}
int main(int argc, char** argv)
{
char* parent="Parent";
char* child1="Child1";
char* child2="Child2";
char result[80];
char buffer[80];
int firstchild,secondchild,read1,read2,read3;
firstchild=fork();
int mypipe[2];
int mypipe2[2];
int mypipe3[2];
if(pipe(mypipe) == -1) {
perror("Pipe failed");
exit(1);
}
if(firstchild == 0) //first child
{
close(mypipe[1]); //Closing the output of pipe
sleep(3);
read1=read(mypipe[0],buffer,sizeof(buffer));
printf("%s\n",buffer);
}else{
secondchild=fork(); //Creating second child
if(secondchild == 0) //2nd child
{
sleep(6);
}else{ //Parent
close(mypipe[0]); //Closing the input of pipe
formatted_time(parent,child1,result);
write(mypipe[1],result,strlen(result)+1);
//printf("%s\n",result);
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);
答案 3 :(得分:1)
我建议使用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
之外,因为fgets
会检查要读取的最大字符数(包括最终的空字符)
见How to read from stdin with fgets()?
答案 4 :(得分:0)
指针变量completeName
未初始化,导致C标准调用未识别的行为。任何事情都可能发生。
您还尝试从函数中返回数组。它们被转换为指向每个数组中第一个元素的指针,并返回该指针。但由于数组是一个局部变量,所谓的&#34;存储类auto&#34;,它在函数返回时消失。 Rhe记忆可以重复用于其他事情,但指针仍然指向内存中的那个位置。同样,行为未定义。
答案 5 :(得分:0)
使用char和fgets数组代替gets。顺便说一句,您的初始代码会在Ubuntu 15.10和gcc(Ubuntu 5.2.1-22ubuntu2)5.2.1 20151010上产生分段错误。
SK