2015-09-20 40 views
0

这是我第一次学习C语言。我只想问你怎么能够在C中返回一个字符串。这就是我正在做的事情。使用C语言从函数返回字符串

int main() 
{ 
    char input[1] = ""; 
    input = setChar(); 
    printf("%s",input); 
} 

char *setChar() 
{ 
    char *character; 
    printf("Enter a new character.\n"); 
    scanf("%s", &character); 
    return character; 
} 

编辑:所以基本上我想有将返回一个字符串或字符值,这将改变从main方法的字符串或字符值的方法。这可能吗?

+0

? – Sim

+1

让问题更加清楚:( – DarKnight

+0

什么是'$ input'? – alk

回答

1

实际上不可能返回字符串,因为字符串是适合模式的值序列。我们将这个值序列存储到一个类型中(通常是一个字符数组),并且我们返回的是类型的(或者指向该类型的指针)。

你的功能是通常返回指向字符串,这可能是你的意思询问...现在我可以看到你的实际目标是我可以指导你在一个指针从一开始就有更好的方向,而不是仅仅指出你发布的程序出了什么问题。

但是我需要使用char返回类型和参数。那可能吗?像“char * setChar()”

我在this answer中写了一些代码。利用该代码,你可以写这样的功能是这样的:

cbar *setChar() { 
    return get_dynamic_word(stdin); 
} 

与该代码,您main功能应该是这个样子:

int main(void) { 
    char *input = setChar(); 
    if (input == NULL) { 
     exit(EXIT_FAILURE); 
    } 

    printf("%s", input); 
    free(input); 
} 

有几件事情错了与此计划。让我们一次确定一行。

int main() 

虽然这可能平时工作,它不提供独立的环境(你的操作系统)与特定的原型。在C标准的话,

在一个函数声明是不是该函数的定义的部分的空列表指定没有关于参数的数目或类型的信息被提供。

这个概念最好由缺少错误消息证明,即使有严格的指示警告应该是错误标志进行编译时:

int main() { 
    return main(42, 42, 42, 42, 42); 
} 

所以这两个原型(或equivelant)它会选择吗?

int main(void) { /* ... */ } 

int main(int argc, char *argv[]) { /* ... */ } 

从技术上讲,该行为是不确定的。

关于未定义行为的快速提示:有些人会写道,可能会发生“崩溃”,而不是。将未定义的行为定义为“崩溃”是错误的;这可能会像你期望的那样工作,但这不是C标准的要求。所以如果你改变了编译器,或者你的操作系统更新,或者其他一些微小的改变(比如用户输入),那么你可能会开始看到你的程序出现故障。

您应该坚持前面提到的main的两个原型之一。

顺便说一下,很明显你可能没有从书中学习。 K & R(第二版)已经试过&已经测试了几十年,并且已经证明可以成功教授数千名学生。 确保你做了练习。


char input[1] = ""; 

字符串是字符的序列,其终止于第一'\0'(又名0,不与'0'混淆(见引号),它通常是48)。你可能会注意到,如果你printf("%d\n", input[0]);input中的第一个(也是唯一的)字符被初始化为0

您可以存储多少个字符值到input?只有一个,因为你宣称它只是一个字符。这意味着您只能将一种字符串存储到此数组中:一个空的之一。

当您决定使用您的存储字符串的数组的多长时间时,您需要适应字符串的零(零)终止。如果您要声明inputchar input[256];(如其他答案中所示),input可以存储255个非零字符,后跟1个零字符来终止字符串。


input = setChar(input); 

这行代码在技术上是违反约束;你的编译器应该产生一个错误信息。你不能像这样分配数组。不用担心,这是一个简单的解决方法,因为返回值是多余的;你的函数直接修改数组。利用这一点,来代替:

setChar(input); 

printf("%s",$input); 

您还没有宣布任何这样的标识符$input,而事实上,因为C标准不要求$字符存在于源字符集中,那么这将是一个错误。我想你的意思是这样写:

printf("%s", input); 

scanf("%s", &c); 

有两个问题:

  • 当1以外scanf回报什么,可能发生了IO错误,并且c可能不包含一个字符串(这意味着你不应该骗到printf,并告诉它打印一个非字符串,就像它是一个字符串一样......请参阅关于未定义行为的注释)。 不要忽略scanf的返回值。永远。
  • 格式指令%s告诉scanf,你给它的参数是一个char *,但使用&操作上char *产生char ** ...你骗scanf,这也是不确定的行为。

你大概意思写的东西,如:

int x = scanf("%s", c); 
if (x == 1) { 
    return c; 
} 
else { 
    return NULL; 
} 

这将使你的返回值的目的:你能确定你的函数是否是成功的,当你把它叫做:

char *str = setChar(input); 
if (str == NULL) { 
    /* An error occured */ 
} 
else { 
    /* c -should- contain a string */ 
} 

我这样说应该包含一个字符串,因为有些情况下它可能不会。其他人提到了缓冲区溢出的问题。这些可以通过告诉scanf避免你的阵列有多大,在这种情况下,一个字符串可以保证:

char input[256]; 
int x = scanf("%255s", input); 

产生了一个问题,这就是如果一个特定的词,会发生什么(因为%s读取)长超过255个字符。 scanf将停止阅读,留下下一个电话scanf(或getchar,或其他)处理的单词的其余部分。如果你想放弃这样一个字的剩余部分,上面的代码可以通过这个随访:

scanf("%*[^ \n\t]"); 
puts("NOTE: Input truncated!"); 
要返回一个字符串代替焦炭的