2013-07-25 58 views
1

我被困在硬件分配中,在那裏我需要編寫一個程序,將一堆英文單詞(在輸入.txt文件中以換行符分隔的列表中)轉換爲一羣豬拉丁文字(在輸出.txt文件中以換行符分隔)。我已經非常接近了,但我使用的strncat函數(字符串concatentation)函數以某種方式拋出一個新行,這真的拋出了我正在打印的文本到stdout(使用它來測試現在)。任何想法,爲什麼這可能會發生?這裏是我的代碼:C中的字符串處理問題

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define MAX_STR_SIZE 100 

char * convertToPigLatin (char * strPtr, char * pLatinStr); 

int main(int argc, char *argv[]) 
{ 
    char str[MAX_STR_SIZE]; 
    char pStr[MAX_STR_SIZE]; 
    //char *pStrPtr; 
    FILE *fileInPtr;          //Create file name 
    FILE *fileOutPtr;  

    fileInPtr = fopen("pigLatinIn.txt", "r"); //Assign text to file 
    fileOutPtr = fopen("pigLatinOut.txt", "w"); 

    //pStrPtr = pStr; 

    if(fileInPtr == NULL)        //Check if file exists 
    { 
     printf("Failed"); 
     exit(-1); 
    } 


    do     //Cycles until end of text 
    { 
     fgets(str, 29, fileInPtr);    //Assigns word to *char 

     str[29] = '\0';       //Optional: Whole line 

     convertToPigLatin(str, pStr); 
     fprintf(fileOutPtr, "%s", pStr); 

    } while(!feof(fileInPtr)); 

    system("pause"); 
} 

char * convertToPigLatin (const char * strPtr, char * pStrPtr) 
{ 
    int VowelDetect = 0; 
    int LoopCounter = 0; 
    int consonantCounter = 0; 
    char pStr[MAX_STR_SIZE] = {'\0'}; 
    char cStr[MAX_STR_SIZE] = {'\0'}; 
    char dStr[] = {'-','\0'}; 
    char ayStr[] = {'a','y','\0'}; 
    char wayStr[] = {'w','a','y','\0'}; 

    pStrPtr = pStr; 

    while (*strPtr != '\0') 
    { 
     if (*strPtr == 'a' || *strPtr == 'e' || *strPtr == 'i' || *strPtr == 'o' || *strPtr == 'u' || VowelDetect ==1) 
     { 
     strncat(pStr, strPtr, 1); 
     VowelDetect = 1; 
     } 
     else 
     { 
     strncat(cStr, strPtr, 1); 
     consonantCounter++; 
     } 
     *strPtr++; 
    } 
    strcat(pStr, dStr); 
    if (consonantCounter == 0) 
    { 
     strcat(pStr, wayStr); 
    } 
    else 
    { 
     strcat(pStr, cStr); 
     strcat(pStr, ayStr); 
    } 
    printf("%s", pStr);      

// return pStrPtr; 
} 
+3

你想快速,痛苦還是緩慢無痛? – chris

+0

我的猜測*是你至少有一行的字符數小於你用'fgets()'讀的'29'的字符數,因此你的循環中只有一個嵌入的CR或LF, strcat's到你的字符串,因爲你不排除任何這些字符。是什麼讓你決定一次任意讀取29個字符,並假定它是一行? –

+0

是的,我不認爲'strncat()'增加了一個換行符,只是'fgets()'正在讀取已經在輸入文件中的文件。在通過'convertToPigLatin()'運行之前,您應該將其去掉。 –

回答

2

有多種在這段代碼古怪的,但你問的是你的while循環convertToPigLatin造成的問題。你循環,而*strPtr != '\0',\n肯定不是\0,所以你加入到pStr

現在的代碼的其餘部分,短短評論:

  • 使用strncat複製一個字符爲奇數的使用。通常情況下,人們會使用簡單的字符賦值來代替(如str1[i] = str2[j]
  • *strPtr++正在遞增指針並對其進行解引用,但隨後對解除引用的值無效。那你只需要strPtr++
  • 您可以使用char str[] = "some string"創建字符串文字。你不需要使用數組初始化語法。

那些沒有詳細閱讀就跳到我身上的那些人。祝你未來的任務順利。

編輯以添加通過調試器執行代碼的步驟在這些情況下非常有用。你會準確地看到新行被添加到哪裏。

+0

與'str1 [i] = str2 [j]'串聯,'str'丟失'\ 0'。 (添加'str1 [i + 1] ='\ 0''?) – chux

1

的問題不在於strncat函數,但在你輸入:

fgets(str, 29, fileInPtr);    //Assigns word to *char 
str[29] = '\0';       //Optional: Whole line 

如果輸入超過29個字符以外的東西,硬回車不會被覆蓋。使用這個來代替:

str[strlen(str)-1] = 0; 

..實際上,這將始終覆蓋29號人物,即使它不是一個硬回車(當你輸入超過29個字符)。因此,一個更好的解決辦法是

char *ptr = strchr(str, '\n'); 
if (ptr) *ptr = 0; 

不能使用MAX_STR_SIZE這是(你定義的,但在你的代碼沒有使用),因爲與fgets

[R] EADS從字符流並將它們作爲一個C字符串存儲到str中,直到(num-1)個字符被讀取,或者到達一個換行符或文件結束,以先發生者爲準。 (http://www.cplusplus.com/reference/cstdio/fgets/

- 最後一個字符可能是終止零,或硬返回。

+0

'str [strlen(str)-1] = 0'是有問題的。在不尋常的情況下,'strlen(str)'爲0.OP不會在這裏體驗到它們,但是要避免這種習慣用法。 – chux

+0

同意(需要檢查'strlen(str)> 0',或(short)'if(str [0])')以確保腰帶和吊帶的安全。但是什麼時候需要?輸入文件末尾有一個二進制0,可能在最後一個換行符後面? – usr2564301

+1

1)任何以二進制0開頭的行,例如「\ 0Hello \ n」,不一定是單一的\ \ 0,也不在EOF附近。 'fgets()'停在'\ n'上,而不是'\ 0'。 2)在沒有檢查'fgets()'的返回值的I/O錯誤(或_maybe_ EOF)上,像這樣,使'str'處於未定義狀態。 3)不確定,但也許當'fgets(str,1,...)'。 – chux

0

@selbie是正確的,

*strPtr++; 

==>

++strPtr; 

還添加此之前調用convertToPigLatin

if(str[0] == '\0') 
     break;  

而且它的工作原理,在pigLatinOut.txt表演工作拉丁文,但都在一行!

是這樣的:(我一點都不懂拉丁,是你想要啥子?):

pigLatinIn.txt

hello world! 
I am line one! 
I am line two! 
I am line three! 

pigLatinOut.txt

𬌿\q·ð¬Œ¿\q·ð¬Œ¿\q·ð¬Œ¿\q·