1

我被困在一个硬件任务上,我需要编写一个程序,将一堆英文单词(在输入 .txt 文件中由换行符分隔的列表中)转换为一堆 Pig 拉丁文单词(到一个列表中由输出 .txt 文件中的新行分隔)。我已经非常接近了,但是strncat我正在使用的函数(字符串连接)函数以某种方式抛出了一个新行,这真的抛出了我正在打印的文本stdout(现在用它来测试)。任何想法为什么会发生这种情况?这是我的代码:

#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; 
}
4

3 回答 3

2

这段代码有很多奇怪之处,但是您要问的问题是由您的 while 循环创建的convertToPigLatin。你循环 while *strPtr != '\0'\n当然不是\0,所以你将它添加到pStr.

现在对于其余的代码,只需添加一些注释:

  • 用于strncat复制一个字符是奇怪的用法。通常,人们会使用简单的字符分配来代替(如str1[i] = str2[j]
  • *strPtr++正在递增指针并取消引用它,但随后对取消引用的值不做任何事情。你只是想strPtr++在那里。
  • 您可以使用创建字符串文字char str[] = "some string"。您不需要使用数组初始化语法。

那些是在没有详细阅读的情况下跳出来的。祝你未来的任务好运。

编辑以添加在这些情况下使用调试器单步执行代码非常有价值。您将准确看到添加换行符的位置。

于 2013-07-25T00:58:14.047 回答
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] 从流中读取字符并将它们作为 C 字符串存储到 str 中,直到读取 (num-1) 个字符或到达换行符或文件结尾,以先发生者为准。( http://www.cplusplus.com/reference/cstdio/fgets/ )

-- 最后一个字符可以是终止的零,也可以是硬返回。

于 2013-07-25T01:00:23.413 回答
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·
于 2013-07-25T01:27:16.440 回答