Justin1 发表于 2020-8-23 09:04:37

(问题更改)图的创建scanf()使用出现的问题

本帖最后由 Justin1 于 2020-8-23 14:52 编辑

读《大话数据结构》的时候,有一个scanf的细节,有点疑惑,没有传统的转换说明,单纯读入一个地址。就不大明白,这样操作真的可以吗?我试了试好像有点问题。自己去官方文档上看也没看个所以然来。


我更改并且补齐了代码,想要试着打印一边矩阵和顶点数组。
现在,我想每次顶点上读入的是一个字符,a,b,c,d但是出现了问题,程序中只能读取两个a,b

#include<stdio.h>
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)
typedef char VertexType; /* 顶点类型应由用户定义 */
typedef int EdgeType; /* 边上的权值类型应由用户定义 */
#define MAXVEX 100 /* 最大顶点数,应由用户定义 */
#define INFINITY 65535/* 用65535代表正无穷*/
typedef struct
{
    VertexType vexs; /* 顶点表 */
    EdgeType arc;/* 邻接矩阵,可看作边表 */
    int numNodes, numEdges; /* 图中当前的顶点数和边数 */
}MGraph;

/* 建立无向网图的邻接矩阵表示 */
void CreateMGraph(MGraph* G)
{
    int i, j, k, w;
    printf("输入顶点数和边数:\n");
    scanf("%d,%d", &G->numNodes, &G->numEdges); /* 输入顶点数和边数 */
    for (i = 0; i < G->numNodes; i++) /* 读入顶点信息,建立顶点表 */
    {
      printf("the value of Node\n");
      scanf("%c", &(G->vexs));
    }

    for (i = 0; i < G->numNodes; i++)
      for (j = 0; j < G->numNodes; j++)
            G->arc = INFINITY; /* 邻接矩阵初始化 */
    for (k = 0; k < G->numEdges; k++) /* 读入numEdges条边,建立邻接矩阵 */
    {
      printf("输入边(vi,vj)上的下标i,下标j和权w:\n");
      scanf("%d,%d,%d", &i, &j, &w); /* 输入边(vi,vj)上的权w */
      G->arc = w;
      G->arc = G->arc; /* 因为是无向图,矩阵对称 */
    }
}

//这一部分是我自己加的,没有写完整,大致为了采用for循环读取矩阵的值从而检验程序是否正常运行
//为了方便,我默认输入顶点数为4,所以有 i < 4
int main(void)
{
    int i, j;
    MGraph G;
    CreateMGraph(&G);
    printf("========区分函数和主函数打印==========\n");
    for (i = 0; i < 4; i++) {
      printf("%c\n", G.vexs);
      printf("=====区分顶点数组和矩阵=====\n");
      for (j = 0; j < 4; j++)
      {
            printf("%d\n", G.arc);
      }
    }
    return 0;
    getchar();
}


想要这样的结果,还是出现了问题{:9_234:}

这个是运行截图
很明显看到我的测试输出
printf("the value of Node\n");
在循环中直接打印了两次才录入一个信息,这点我不太明白,希望有想法的鱼酱们帮忙解答下

zltzlt 发表于 2020-8-23 09:19:44

这样用是错的吧

永恒的蓝色梦想 发表于 2020-8-23 09:43:47

麻烦把 MGragh 的代码也发一下。

Justin1 发表于 2020-8-23 11:06:52

永恒的蓝色梦想 发表于 2020-8-23 09:43
麻烦把 MGragh 的代码也发一下。

补上书上代码啦

Justin1 发表于 2020-8-23 11:07:37

zltzlt 发表于 2020-8-23 09:19
这样用是错的吧

我也感觉,不过自己补上补充说明,尝试测试了下,结果也有问题

永恒的蓝色梦想 发表于 2020-8-23 11:09:47

Justin1 发表于 2020-8-23 11:07
我也感觉,不过自己补上补充说明,尝试测试了下,结果也有问题

这个肯定是错了。这个 scanf 什么也读不进来。

405794672 发表于 2020-8-23 11:10:45

以我的想法,应该不需要%d。这是格式输入,即把输入的部分当作此格式填入某地址处。或者,读取输入的符合格式的部分,填入地址处。如果没有限定此格式,那么应该是原封不动的填入所有输入的东西到某地址处。

永恒的蓝色梦想 发表于 2020-8-23 11:16:01

405794672 发表于 2020-8-23 11:10
以我的想法,应该不需要%d。这是格式输入,即把输入的部分当作此格式填入某地址处。或者,读取输入的符合格 ...

1.scanf 必须提供格式化字符串。
2.这里根本没有提供“某地址”。

Justin1 发表于 2020-8-23 11:32:33

405794672 发表于 2020-8-23 11:10
以我的想法,应该不需要%d。这是格式输入,即把输入的部分当作此格式填入某地址处。或者,读取输入的符合格 ...

强行理解是按照你这样来的,不过运行不出来。 很奇怪的是就算加了%c,还是会有问题,什么堆栈溢出之类的

405794672 发表于 2020-8-23 12:22:33

Justin1 发表于 2020-8-23 11:32
强行理解是按照你这样来的,不过运行不出来。 很奇怪的是就算加了,还是会有问题,什么堆栈溢出之类的

你加%C当然不行。因为你那个地址里天知道存了多大的内容。%C只能取一个字符。如果你知道那个地址有多大,可以以相同的大小的格式进行试试。

405794672 发表于 2020-8-23 12:25:00

本帖最后由 405794672 于 2020-8-24 09:35 编辑

{:5_103:}

永恒的蓝色梦想 发表于 2020-8-23 12:30:57

405794672 发表于 2020-8-23 12:25
我不知道1对不对,你可以试试。但2,这里提供了地址。那个&符号我看见了。

那个地址是第一个参数,是格式化字符串的位置。

405794672 发表于 2020-8-23 13:57:18

本帖最后由 405794672 于 2020-8-24 09:35 编辑

{:5_104:}

永恒的蓝色梦想 发表于 2020-8-23 14:27:20

405794672 发表于 2020-8-23 13:57
是啊,是地址就行了啦!你可能无法理解。希望你好好理解我的想法吧,还可以试验一下。我的想法不是一般 ...

对,所以你说,填入输入的东西去哪了呢?
理解了错误的思维贻害无穷吧。

Justin1 发表于 2020-8-23 14:38:38

永恒的蓝色梦想 发表于 2020-8-23 14:27
对,所以你说,填入输入的东西去哪了呢?
理解了错误的思维贻害无穷吧。

我又改了一下,想输入字符,得到书上的图的结果,但还是有些问题。。希望有时间能帮忙看看啊,如果表达不清晰的地方也多多指正,记住了下次发贴就知道了。

Justin1 发表于 2020-8-23 14:40:04

405794672 发表于 2020-8-23 13:57
是啊,是地址就行了啦!你可能无法理解。希望你好好理解我的想法吧,还可以试验一下。我的想法不是一般 ...

额,我感觉你说的是直接修改地址上的值,但试了下不行,官方文档也没找到类似的。我改了下程序,希望有时间帮忙看看哈

Justin1 发表于 2020-8-23 14:53:20

zltzlt 发表于 2020-8-23 09:19
这样用是错的吧

大佬再看看呗{:10_254:}

405794672 发表于 2020-8-23 19:58:28

本帖最后由 405794672 于 2020-8-24 09:37 编辑

{:5_98:} 了

405794672 发表于 2020-8-23 20:00:36

Justin1 发表于 2020-8-23 14:40
额,我感觉你说的是直接修改地址上的值,但试了下不行,官方文档也没找到类似的。我改了下程序,希望有时 ...

很对,我就是这个想法。至于是对是错,完全取决于函数。我这个想法是从你的那个程序上面得来的。这是建立在正确的情况下而想

这段程序究竟能不能运行呢?放进编译器编一下运行一下就知道了。

405794672 发表于 2020-8-23 20:17:12

模拟一下你这张图上的代码,并简化一下:
void main()
{
   struct p{
               int p1;
               int p2;
               int p3;
                } a;//结构体可能要在main外定义
    int i;
   printf("请输入10个数:\n");
   for(i=0;i<10;i++)
   {
      scanf(&a.p3);
    }
printf("输入的数分别为:\n");
for(i=0;i<10;i++)
{
      printf("%d\t",a.p3);
}
}

我觉得已经很像图片上的程序了。运行一下,看看是否有问题。
如果错误,并提示scanf的错误,那说明该图片很可能有问题

另外,现在新版vs中scanf会有警告,要用它,必须预处理忽略警告,具体可以百度
页: [1] 2
查看完整版本: (问题更改)图的创建scanf()使用出现的问题