0

我的代码

char[] fileContents = "hi\n whats up\n";

    char *output=malloc(sizeof(char)*1024) ;

    int i = 0; int j = 0;
    char *bPtr = fileContents;


    for(i=j=0; bPtr[i]!='\0'; i++)
    {
      if('\n'==bPtr[i])
            outputPtr[j++]='\r';
            outputPtr[j++]=bPtr[i];
    }

在 netbeans 上,此代码有效,但使用 linux gcc,\ 和 \n 被视为单独的字符,而在 net beans 中,\n 都是一个字符。请帮助

调试时,在使用 GDB 的 Linux 中,它完全跳过 if 语句,而在 netbeans 中,它进入并完成工作。

4

2 回答 2

0

首先,您的 C 代码不是 C 代码。它很接近,但它根本不会编译。其次,在清理代码使其进入可编译状态后:

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

char fileContents[] = "hi\n whats up\n";

int main(void)
{
  char *output;
  int   i;
  int   j;
  char *bPtr;

  output = malloc(1024);
  bPtr   = fileContents;

  for (i = j = 0 ; bPtr[i] != '\0' ; i++)
  {
    if ('\n' == bPtr[i])
      output[j++] = '\r';
    output[j++] = bPtr[i];
  }

  output[j] = '\0';
  fputs(output,stdout);
  return EXIT_SUCCESS;
}

并使用“gcc -g ac”编译并使用 gdb:

GNU gdb Red Hat Linux (6.3.0.0-1.132.EL4rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db
library "/lib/tls/libthread_db.so.1".

(gdb) break 17
Breakpoint 1 at 0x80483fa: file a.c, line 17.
(gdb) run
Starting program: /tmp/a.out 

Breakpoint 1, main () at a.c:17
17        for (i = j = 0 ; bPtr[i] != '\0' ; i++)
(gdb) n
19          if ('\n' == bPtr[i])
(gdb) n
21          output[j++] = bPtr[i];
(gdb) n
17        for (i = j = 0 ; bPtr[i] != '\0' ; i++)
(gdb) n
19          if ('\n' == bPtr[i])
(gdb) n
21          output[j++] = bPtr[i];
(gdb) n
17        for (i = j = 0 ; bPtr[i] != '\0' ; i++)
(gdb) n
19          if ('\n' == bPtr[i])
(gdb) n
20            output[j++] = '\r';
(gdb) n
21          output[j++] = bPtr[i];

在循环的前两次,我们跳过了条件,因为它是假的。在第三次通过时,满足条件,并且“\r”包含在输出中。

但是通过阅读您的其他一些评论,您似乎对行尾感到困惑。在 Unix 上(因为 Linux 是 Unix 的一种,Linux 也是如此),行以一个字符 LF(ASCII 代码 10)结尾。Windows(和 MS-DOS,Windows 的前身,以及 CP/M,MS-DOS 的前身)使用字符序列 CR LF(ASCII 码 13,ASCII 码 10)来标记行尾。

为什么会有两个不同的标准?由于 ASCII 标准的措辞,它的创建时间和原因。回到它创建的时候,输出主要是电传打字机——想想打字机。CR 定义为将打印托架(或打印头)移回行首,LF 定义为前进到下一行。将打印托架带到下一个开头的动作行未指定。由于标准文档的字面翻译,CP/M(和后代)标准化使用两者来标记行尾。Unix 的创建者决定采用更自由的解释,其中 LF,换行符,意味着前进到下一行进行输出,将打印托架带回到开头(而我使用的第一台计算机使用 CR 来做同样的事情,带来马车回到起点并前进到下一行)。

现在,如果电传打字设备连接到 Unix 系统并且需要 CR 和 LF,则由 Unix 设备驱动程序在看到 LF 时添加所需的 CR。换句话说,系统代表你的程序处理细节,你只需要LF结束一行。

为了进一步混淆混乱,C标准占了上风。当你打开一个文件时,

FILE *fp = fopen("sometextfile.txt","r");

您以“文本”模式打开它。在 Unix 下,这没有任何作用,但在 Windows 下,C 库将丢弃输入时的“\r”,因此程序只需要关心自己寻找“\n”(对于打开写入的文件,它将添加 CR当看到 LF 时)。但这是在 Windows 下(可能还有其他系统可以做到这一点,但我对任何一个都不熟悉)。

如果您真的想按原样查看文件,则需要以二进制模式打开它:

FILE *fp = fopen("sometextfile.txt","rb");

现在,如果文件中有任何 CR,您的程序将看到它们。通常,不需要关心行尾——只有当您将文本文件从一个系统移动到另一个使用不同行尾约定的系统时,它才会成为问题,即便如此,传输机制可能会为您解决问题(例如 FTP)。但检查并没有什么坏处。

还记得我说过 Unix 不区分“文本”和“二进制”模式吗?它没有。因此,来自 Windows 世界的文本文件由 Unix 程序处理,表示 Unix 程序将看到 CR。发生的事情实际上取决于相关程序。像 grep 这样的程序似乎并不关心,但我使用的编辑器会显示任何存在的 CR。

所以我想现在,我的问题是——你想做什么?

于 2013-02-11T05:33:32.977 回答
0

您的代码在我的系统上完美运行gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

我运行的代码:

int main()
{
    char Contents[] = "hi\n whats up\n";

    int i = 0; int j = 0;
    char outputPtr[20];
    for(i=j=0; Contents[i]!='\0'; i++)
    {
      if('\n'==Contents[i]) outputPtr[j++]='\r';
      outputPtr[j++]=Contents[i];
    }
    outputPtr[j]='\0';
    printf("%s %d %d \n", outputPtr,j,i);
    i = 0;
    while(outputPtr[i]!='\0')   printf(" %d ", outputPtr[i++]);
    return 0;
}

输出 :

hi
 whats up
 15 13 //Length of the edited string and the original string
 104  105  13  10  32  119  104  97  116  115  32  117  112  13  10 //Ascii values of the characters of the string 

13 是回车符。

于 2013-02-11T05:19:58.107 回答