【问题标题】:C Programming - Trouble with pointers, no console outputC 编程 - 指针有问题,没有控制台输出
【发布时间】:2017-06-01 20:28:17
【问题描述】:

在对 Java 有了一定程度的适应之后,我现在正努力扩大自己的视野并尝试 C 编程。但是,即使访问了多个视频和网站,我似乎也无法完全理解 C 中的指针。

下面的代码应该从用户那里获取两个字符串,获取它们的长度,然后将长度相互比较。然后程序应该通过指针返回两个名称中最长的一个(非常小心地返回直到换行符的长度,而不是变量的分配大小)。因此,当用户输入 'Peterson'(name1) 和 'Thisisareallylonglastname'(name2) 时,程序应通过指针 / name2 连接返回 'Thisisareallylonglastname'。

我遇到的问题是,当尝试运行代码(使用 Eclipse Neon C/C++ IDE 编写,使用 MinGW 编译器)时,我在控制台中没有输出。我相当确定我已经在 Windows 中正确设置了 MinGW 安装的路径,但要确保我还手动将环境添加到项目中。在我对指针的困惑和通常是一个蹩脚的编码器之间,我不确定我的程序的(无疑是新手)错误是什么。我在 Neon IDE 中没有遇到任何类型的错误。

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

int main(void)
{

    /* Two variables that take family names' input from the user with a maximum length of 256 */
    char name1[256];
    char name2[256];
    char *ch = NULL;

    printf("When two people marry there can sometimes be a debate which last/family name will henceforth be used (as a hyphenated last name is not always feasible.");
    printf("A simple way to avoid squabbles is to simply take the longest family name of the two (soon-to-be) partners.");
    printf("This program will take your name inputs and compare their length against one another; it will then return the longest name to be put on the document.");

    printf("Enter your last name for 1 :");
    gets(name1);
    printf("Enter your last name for 2 :");
    gets(name2);

    int size1 = strlen(name1);
    printf("Length of name 1:");
    printf(size1);

    int size2 = strlen(name2);
    printf("Length of name 2:");
    printf(size2);

    if (size1 > size2)
    {
        ch = &name1;
    }
    else
    {
        ch = &name2;
    }

    if(!ch)
    {
        printf("The largest family name found is:");
        printf(*ch);
    }

    return(0);

}

【问题讨论】:

  • 您需要了解printf 的工作原理,因为printf(size1) 是不正确的。
  • 始终使用正确的格式说明符,即printf(size1); -> printf("%d", size1); & printf(size2); -> printf("%d", size2); & 我猜是 printf(*ch);应该是printf("%s", ch);
  • 在玩过 Java 之后,尝试 C++ 而不是 C 会更“自然”(同样的 OOP用于输入/输出...)。
  • 从不使用gets。它不再是 C 标准的一部分。请改用fgets。

标签: c eclipse pointers mingw


【解决方案1】:

一个主要问题是您的最终输出处于if (!ch) 条件下 - 在英文中,它的意思是“如果指针 ch 是 null-valued”。因为它指向两个(非null)内存位置之一,所以这个检查永远不会通过。

如果您将其更改为if (ch)(或者只是省略检查,因为我们知道它不是null)并修复cmets中其他人指出的printf问题,我认为您会得到更好的结果.

【讨论】:

    【解决方案2】:

    指向 char 的指针和 char 数组都是 C 中表示字符串的两种方式,因此是相同的类型。主要区别在于,数组的内存是在编译时分配的,使用指针可以为它分配一个数组(就像您尝试做的那样)或动态分配内存。

    所以当你在做的时候

    ch = &name1;
    

    您实际上正在尝试将指向字符串 name1 的指针分配给 ch,这不是同一类型,应该会引发错误。相反,你真的很想做

    ch = name1;
    

    相反,*ch 与 ch[0] 相同 - 您正在访问字符串的第一个字符,以便将其打印出来

    printf("%s",ch);
    

    【讨论】:

      【解决方案3】:
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      int main(void)
      {
      
          /* Two variables that take family names' input from the user with a maximum length of 256 */
          char name1[256];
          char name2[256];
          char *ch = NULL;
      
          printf("When two people marry there can sometimes be a debate which last/family name will henceforth be used (as a hyphenated last name is not always feasible.");
          printf("A simple way to avoid squabbles is to simply take the longest family name of the two (soon-to-be) partners.");
          printf("This program will take your name inputs and compare their length against one another; it will then return the longest name to be put on the document.");
      
          printf("Enter your last name for 1 :");
          gets(name1);
          printf("Enter your last name for 2 :");
          gets(name2);
      
          int size1 = strlen(name1);
          printf("Length of name 1: %d", size1);
      
      
          int size2 = strlen(name2);
          printf("Length of name 2: %d", size2);
      
          if (size1 > size2)
          {
              ch = name1;
          }
          else
          {
              ch = name2;
          }
      
      
          printf("The largest family name found is: %s", ch);
      
      
      
          return(0);
      
      }
      

      这应该可以解决问题。您还应该使用scanf("%s", str) 而不是gets。

      当您执行char name1[256] 时,name1 被“视为指针”,因此您必须执行ch = name1 而不是ch = &amp;name1,因为ch 和name1 都是指针。

      当你这样做时:

      if(!ch)
      {
        printf...
      }
      

      只有当 ch 为 null 时才会打印,这是你不想要的,因为在这种情况下,如果 ch 有值,你就想打印,所以你应该这样做:

      if(ch)
      {
        printf...
      }
      

      在c printf 中也必须接收有关您尝试打印的变量的信息,请查看 printf 示例以了解它

      【讨论】:

      • 请添加有关为您的答案所做的选择的更多详细信息。不仅是源代码。
      【解决方案4】:

      main 问题是您期望 printf 充当像 System.out.println 这样的多态函数,但事实并非如此。 printf 的原型是

      int printf( const char * restrict format, ... );
      

      第一个参数是总是一个字符串;字符串可能包含转换说明符,这些说明符控制任何其他参数的格式。

      所以不要写:

      printf("Length of name 1:");
      printf(size1);
      

      你会写:

      printf( "Length of name 1: %d\n", size1 );
      

      或

      printf( "Length of name 1: " );
      printf( "%d\n", size1 );
      

      格式字符串中的%d 告诉printf,相应的参数应该具有int 类型,并且您希望将其值显示为十进制数字字符串。有关转换说明符的完整列表,请参阅 online C 2011 standard 的第 7.21.6.1 节。

      printf 不会像System.out.println 那样自动将换行符附加到所有输出 - 您必须在格式字符串 (\n) 中指定它。

      标准输出通常是行缓冲 - 输出不会显示在控制台上,直到 a) 缓冲区已满,b) 使用 fflush 手动刷新缓冲区,c) 换行出现在缓冲区中,或 d) 输入函数(fgets、scanf 等)紧跟输出函数。

      C 和 Java 中的数组语义非常不同。在 C 中,数组不是引用对象——它们不指向堆上动态分配的内存。但是,数组下标操作a[i] 是根据指针算术定义的 - *(a + i)。在 C 中发生的情况是,当数组 expression 不是 sizeof 或一元 &amp; 运算符的操作数,或者不是用于在声明中初始化数组的字符串文字时,表达式从“T 的 N 元素数组”类型转换(“decays”)为“指向T 的指针”,表达式的值是数组第一个元素的地址。

      这是一种非常啰嗦的说法,而不是写作

       ch = &name1;
      

      你应该写作

       ch = name1;
      

      相反。 表达式 name1“衰减”为指向数组第一个元素的指针,表达式的结果类型为char *。表达式&amp;name1 的类型是char (*)[256](指向char 的256 元素数组的指针),这不是您想要的。它们都将评估到相同的位置(以任何类型转换为模),但类型很重要。

      终于……

      永远不要永远不要使用gets。它将在您的代码中引入故障点/主要安全漏洞。它在 C99 标准发布后不久就被弃用,并在 C2011 中正式从标准库中删除。几十年来,这个图书馆功能一直是造成无数混乱的罪魁祸首。不要使用它,即使在玩具代码中也不行。它是 C 编程语言的“Highlander II”——它从未存在。请改用fgets。

      【讨论】:

        猜你喜欢
        • 2014-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多