2014-09-10 30 views
0

我做了一個程序,它接收2到5個字符串,並使用可變參數函數連接在一起。使用可變參數函數連接字符串

到目前爲止程序工作正常,但它總是在顯示完整的字符串之前顯示3個隨機字符。

例如:

Please insert number of strings: 3 
string 1: car 
string 2: bike 
string 3: plane 

完全字符串:

=$>carbikeplane 

我作了一些調整,以程序試圖找到原因並修復它,但我總是得到相同的結果。

完整的程序如下所示。 有關該計劃的幾點意見:

  1. 我打印在程序的不同部分的琴絃,因爲我試圖找出哪裏出了問題來了。所以一些printf()函數可能沒有意義。
  2. 主要功能似乎很好,問題出在稍後定義的功能上。

注意:我還在學習C語言,所以可能會有一些代碼可能/可能會創建未定義的行爲,如果有的話,我會很感激,如果您能指出這些。

#include <stdio.h> 
#include <string.h> 
#include <stdarg.h> 

char *function(int num, ...); 

int main(void) 
{ 
    char line1[80] = " ", line2[80] = " ", line3[80] = " ", line4[80] = " ", line5[80] = " "; 
    int count = 0, count2; 
    char *newStr; 
    int i; 
    int status; 

    do { 
     fflush(stdin); 
     printf("\nPlease select the number of strings (max. 5): "); 
     scanf("%d", &count); 

    }while(count < 2 && count > 5); 

    count2 = count; 
    fflush(stdin); 

    status = 1; 
    for(i = 1 ; count > 0; count--, i++) 
    { 
     switch(status) 
     { 
      case 1: 
      { 
       printf("\nInput string[%d]: ", i); 
       gets(line1); 
       status = 2; 
       break; 
      } 
      case 2: 
      { 
       printf("\nInput string[%d]: ", i); 
       gets(line2); 
       status = 3; 
       break; 
      } 
      case 3: 
      { 
       printf("\nInput string[%d]: ", i); 
       gets(line3); 
       status = 4; 
       break; 
      } 
      case 4: 
      { 
       printf("\nInput string[%d]: ", i); 
       gets(line4); 
       status = 5; 
       break; 
      } 
      case 5: 
      { 
       printf("\nInput string[%d]: ", i); 
       gets(line5); 
       status = 6; 
       break; 
      } 
     } 

    } 
     printf("\n%s\n%s\n%s\n%s\n%s\n", line1, line2, line3, line4, line5); 
    /*call the function of variable arguments*/ 
     /*memory allocation of newstr*/ 
     newStr = (char *)malloc(420*sizeof(char) +1); 
    switch(count2) 
    { 
     case 2: 
     { 
      newStr = function(2, line1, line2); 
      break; 
     } 
     case 3: 
     { 
      newStr = function(3, line1, line2, line3); 
      break; 
     } 
     case 4: 
     { 
      newStr = function(4, line1, line2, line3, line4); 
      break; 
     } 
     case 5: 
     { 
      newStr = function(5, line1, line2, line3, line4, line5); 
     } 
    } 

    printf("\nThe final string is: \n"); 
    printf("%s", newStr); 

    return 0; 

} 


char *function(int num, ...) 
{ 
    va_list arg_ptr; 
    int b; 
    char *string; 
    char *curstr; 

    va_start(arg_ptr, num);  /*initialize the arg_ptr*/ 

    string = (char *)malloc(420*sizeof(char) + 1); 
    *string = " "; 

    for(b=0; b < num; b++) 
    { 
     curstr = va_arg(arg_ptr, char *); 
     string = strcat(string,curstr); 
    } 

    printf("\n%s", string); 

    va_end(arg_ptr); 

    return string; 

} 
+4

你用什麼編譯器簡單地完成,結束輸入時按ctrl+d? '* string =「」;'無效並且不應該編譯... – fritzone 2014-09-10 08:18:41

+4

每日提醒不要投入'malloc()'的返回值。 – Igor 2014-09-10 08:20:10

+1

要完成@Igor語句,我建議你閱讀這個問題,因爲我認爲這是一個有趣的事情要了解:http://stackoverflow.com/questions/605845/do-i-cast-the-result-of- malloc – Logar 2014-09-10 08:22:52

回答

4

真正的問題是,你可以編譯行:*string = " ";這已不再有效,並且應該不會編譯。假設你在那裏放置該行來初始化你的字符串以獲得初始值。但是,這可以很容易地通過分配這樣的字符串來解決:

string = calloc(420, sizeof(char)); 

即:使用calloc其設置內存爲零。這樣你有一個可以被strcat使用的有效字符串。

我不告訴你不要使用getsfflush,因爲很顯然這是一個家庭任務,並且建議的fgets在處理輸入字符串時有其自身的問題。當然,如果您在生產代碼中使用gets,那麼當時有人會踢你。

而關於再次施放返回值malloc,這是一把雙面劍。如果你確實知道你將編譯你的項目爲一個C項目(即:文件名以.c結尾,並使用gcc編譯),那麼是的。不要投。但是在其他情況下,例如命名文件.cpp或使用g ++編譯....以及。你會得到錯誤:error: invalid conversion from ‘void*’ to ‘char*’沒有演員。而且我有這樣的感覺,即在初學者的水平上,在爲學校完成家庭作業時,你或多或少集中精力使你的代碼編譯和運行,而不是堅持迂腐。但是,對於將來,建議你會迂腐。

+0

順便說一句:'規格sizeof(char)== 1'。 – datenwolf 2014-09-10 09:21:52

+0

@fritzone該程序現在工作,由於calloc函數和刪除「」,感謝您的建議。我還沒有進入C++,但最終會。 我不在學校heheheheheheh,只是自己學習幾本書。 – 2014-09-10 09:23:38

-1

您的代碼長度與用戶可以輸入的最大字符串成比例。這聽起來不太好,對吧? (如果將來有人會要求你改變它以允許用戶輸入10個字符串?20?100 ???)。

在這種情況下,通常是在幫助從何陣列 - 而不是有5個不同的變量,只是使用其中的一個數組:

因此改變:

char line1[80], line2[80], line3[80], line4[80], line5[80]; 

到:

char lines[5][80]; 

所以當需要設置例如第二個字符串,你可以得到它通過:

char* line2 = lines[1]; \\ remember about indexes starting from 0, 
         \\ so second element has index 1 

所以現在不是5開關的情況下,你可以去:

for(i = 1 ; count > 0; count--, i++) 
{ 
    printf("\nInput string[%d]: ", i); 
    fgets(lines[i], 80, stdin); 
} 

而且你不需要可變參數的功能,你可以只通過陣列和它的大小:

char *function(int array_elements, char ** array); 
//Usage: 
concatenated_string = function(5, lines); 

而且這是很好的做法,把所有常量的值到變量(改變字符串用戶的最大數量可以進入的時候是這樣,你只需要改變一個地方)。

const int MAX_STRINGS = 5; 
const int MAX_STRING_LENGTH = 80; 

現在到了真正的問題:

string = (char *)malloc(420*sizeof(char) + 1); 
*string = " "; 

爲什麼你會分配420個字節?如果用戶只輸入一個字符串 - 如果剩餘340個字節需要什麼?

要獲得連接字符串的長度,遍歷行(從0到array_size),獲取行的長度(帶有strlen),將它們相加在一起併爲尾部'\ 0'加1。現在你不會分配任何不必要的內存。

下一頁 - *string = " ";不應該作爲編譯是*string一個char" "我一個字符串(字符*)。改爲*string = '\0',或撥打calloc而不是malloc

+0

謝謝,有用的信息。然而,我在做的這個練習嚴格地集中在使用可變參數函數。無論如何,我覺得你的評論非常有用。 – 2014-09-10 09:26:21

+0

分配的內存量仍然適用 – zoska 2014-09-10 09:59:55

-2

這是修改後的代碼工作正常

#include <stdio.h> 
    #include <string.h> 
    #include<stdlib.h> 
    #include <stdarg.h> 

    char *function(int num, ...); 

    int main(void) 
    { 
     char line1[80] = " ", line2[80] = " ", line3[80] = " ", line4[80] = " ", line5[80] = " "; 
     int count = 0, count2; 
     char *newStr; 
     int i; 
     int status; 

     do { 
      fflush(stdin); 
      printf("\nPlease select the number of strings (max. 5): "); 
      scanf("%d", &count); 

     }while(count < 2 && count > 5); 

     count2 = count; 
     fflush(stdin); 

     status = 1; 
     for(i = 1 ; count > 0; count--, i++) 
     { 
      switch(status) 
      { 
       case 1: 
       { 
        printf("\nInput string[%d]: ", i); 
        gets(line1); 
        status = 2; 
        break; 
       } 
       case 2: 
       { 
        printf("\nInput string[%d]: ", i); 
        gets(line2); 
        status = 3; 
        break; 
       } 
       case 3: 
       { 
        printf("\nInput string[%d]: ", i); 
        gets(line3); 
        status = 4; 
        break; 
       } 
       case 4: 
       { 
        printf("\nInput string[%d]: ", i); 
        gets(line4); 
        status = 5; 
        break; 
       } 
       case 5: 
       { 
        printf("\nInput string[%d]: ", i); 
        gets(line5); 
        status = 6; 
        break; 
       } 
      } 

     } 
      printf("\n%s\n%s\n%s\n%s\n%s\n", line1, line2, line3, line4, line5); 
     /*call the function of variable arguments*/ 
      /*memory allocation of newstr*/ 
      newStr = (char *)malloc(420*sizeof(char) +1); 
     switch(count2) 
     { 
      case 2: 
      { 
       newStr = function(2, line1, line2); 
       break; 
      } 
      case 3: 
      { 
       newStr = function(3, line1, line2, line3); 
       break; 
      } 
      case 4: 
      { 
       newStr = function(4, line1, line2, line3, line4); 
       break; 
      } 
      case 5: 
      { 
       newStr = function(5, line1, line2, line3, line4, line5); 
      } 
     } 

     printf("\nThe final string is: \n"); 
     printf("%s", newStr); 

     return 0; 

    } 


    char *function(int num, ...) 
    { 
     va_list arg_ptr; 
     int b; 
     char *string; 
     char *curstr; 

     va_start(arg_ptr, num);  /*initialize the arg_ptr*/ 

     string = (char *)malloc(420*sizeof(char) + 1); 
     //*string = " "; 

     for(b=0; b < num; b++) 
     { 
      curstr = va_arg(arg_ptr, char *); 
      string = strcat(string,curstr); 
     } 

     printf("\n%s", string); 

     va_end(arg_ptr); 

     return string; 

    } 

就包括STDLIB和評論*串

有一個愉快的一天

+1

這段代碼是完全不好的(是的,也許它會工作和編譯,但最好不要重複OP在代碼設計本身所犯的錯誤) – zoska 2014-09-10 08:54:39

+0

但由於他是一個新用戶,所以將簡化他的辛勤工作,反正我沒有試圖完全解釋這個概念 – Ashok 2014-09-10 09:42:25

0

這裏是連接儘可能多的字符串作爲一個快速和骯髒的方式用戶想要進入。

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

char *concat (const char *str1, const char *str2) { 

    size_t len1 = strlen (str1);   /* get lenghts */ 
    size_t len2 = strlen (str2); 

    char * s = malloc (len1 + len2 + 2); /* allocate s and concat with ' ' */ 
    memcpy (s, str1, len1); 
    s [len1] = ' '; 
    memcpy(s + len1 + 1, str2, len2); /* does not include terminating null */ 
    s [len1 + len2 + 1] = '\0';  /* force null termination   */ 

    return s; 
} 

int main (void) { 

    char *line = NULL; /* pointer to use with getline() */ 
    ssize_t read = 0; 
    size_t n = 0; 
    int cnt = 0; 
    char *str; 

    printf ("\nEnter a line of text to concatenate (or ctrl+d to quit)\n\n"); 

    while (printf (" input: ") && (read = getline (&line, &n, stdin)) != -1) { 

     if (line[read-1] == '\n') {  /* strip newline */ 
      line[read-1] = 0; 
      read--; 
     } 

     if (cnt == 0)     /* if more than 1 word, concat */ 
      str = strdup (line); 
     else 
      str = concat (str, line); 

     cnt++; 
    } 

    printf ("\n\n Concatenated string: %s\n\n", str); 

    return 0; 

} 

輸出:

$ ./bin/concat 

Enter a line of text to concatenate (or ctrl+d to quit) 

    input: my dog 
    input: has lots of fleas 
    input: my cat 
    input: has some too. 
    input: 

    Concatenated string: my dog has lots of fleas my cat has some too. 
相關問題