【问题标题】:32bit C program no longer converting char to int on 64 bit OS Linux32 位 C 程序不再在 64 位 OS Linux 上将 char 转换为 int
【发布时间】:2015-06-21 22:17:38
【问题描述】:

一个简单的问题:

这个功能在我的 32 位 Linux 上完美运行,然后我得到了一个 64 位 Linux,现在它不再工作了。在将数据从 Char 转换为 Int 时,我已将其范围缩小到此函数。它不再这样做了。这就是我现在所困的地方。所有这些函数所做的就是采用像这样的 100x100 格式,然后切掉 x 并在两边保留两个数字,然后将它们更改为 Int。

使用 atoi 现在返回垃圾,因为我在这个 64 位 Linux 上运行它。我必须使用什么函数调用才能使它现在只能在 32 位和 64 位 Linux 程序上再次工作?

int findX(char *whereisX, int *rW, int *rH)
{
printf("entering findx dia is %s\n\n", whereisX);
char *tok1, *tok2, *saveptr;
char x = (int) malloc(sizeof(whereisX));

char str1[x];
int bW, bH;

strcpy(str1, whereisX);

tok1 = strtok_r(whereisX, "x", &saveptr);
tok2 = strtok_r(NULL, "x", &saveptr);

if ( tok2 == NULL)
{   printf("found return 1\n");
    return 1;
}
 else
    { printf("returning 0\n");
        tok1 = strtok_r(str1, "x", &saveptr);
        tok2 = strtok_r(NULL, "x", &saveptr);

        printf("tok1 is .. %s and tok2 is %s\n", tok1 , tok2);

    // here is where I am converting it from Char to Int
    // using atoi now gives me back junk 

     // bW = atoi(tok1);
     //    bH = atoi(tok2);


    bW = atoll(tok1);
    bH = atoll(tok2);
        printf("bW is %c and bH is %c\n", bW, bH);
       // printf("string -- bW is %s and bH is %s\n", bW,bH);
    /* assigning the results to the output */
       *rW = bW;
       *rH = bH;
    printf("rW is %s  rH is %s\n", rW  , rH); 
       return 0;
     }
} //end findX

输出是

tok1 is .. 200 and tok2 is 100
// after converting from char to int using atoi
bW is � and bH is d
rW is �  rH is d

【问题讨论】:

  • char x = (int) malloc(sizeof(whereisX)); 没有意义。
  • 检查函数的 3d 线...
  • 至少两个错误:废话mallocprintf("bW is %c and bH is %c\n", bW, bH);:如果bW和bH是int,那么你应该使用%d
  • 我不关心 printf,因为我不是一个经验丰富的程序员永远不会有两个原因——我只是把它们扔进去,看看我的代码发生了什么—— - 我只是把这段代码添加到它上面,使程序给我更多的权力来做我想做的任何事情,然后是其他人做的事情。 printf 将被删除。这是我用 C 编写的唯一程序,很可能也是最后一个程序 @xanatos

标签: c linux 32bit-64bit


【解决方案1】:

这些用于分配内存以复制传递的字符串的行是无稽之谈。

char x = (int) malloc(sizeof(whereisX));    // does not give the string length
char str1[x];                               // does not allow for terminator
int bW, bH;
strcpy(str1, whereisX);

会更好

char str1[1+strlen(whereisX)];
strcpy(str1, whereisX);

奇怪的是,您的早期版本完全有效!

编辑

让我们来看看吧:

char x = (int) malloc(sizeof(whereisX));

mallocchar* 指针分配内存 - 以前是 4 个字节,现在是 8 个。

(int)malloc 将分配的内存地址转换为整数。

char x = 然后将整数存储在 8 位中。这与您将复制的字符串的长度无关。

接下来char str1[x]; 分配一个大小与您将复制的字符串长度完全无关的数组。即使您确实有正确的长度,它也需要长一个元素才能使用nul 终止符。如果它以前有效,那么您最终得到了一个足够长的数组,这纯属幸运。

但是切换到不同的编译器出现了这个错误。

因此,与其说我没有回答你的问题,不如更正你的错误,看看它是否能解决问题。也许会,也许不会:我没有看过第 3 行,看是否还有其他 howlers

【讨论】:

  • 它只给了我"" mhsetroot-v1.6.2.c:在函数'findX'中:mhsetroot-v1.6.2.c:728:11:警告:从指针转换为不同的整数size [-Wpointer-to-int-cast] "" 并且它仍然有效但我必须添加:将其更改为您建议的解决了我的问题 --- 谢谢!!!!!! @WeatherVane
  • @uxserx-bw 不要通过对警告进行强制转换来修复警告;而是尝试了解警告试图警告您的内容
【解决方案2】:

您的代码的正确版本是:

int findX(char *whereisX, int *rW, int *rH)
{
    printf("entering findx dia is %s\n\n", whereisX);
    char *tok1, *tok2, *saveptr;

    char *str1 = (char*)malloc(1 + strlen(whereisX));
    int bW, bH;

    strcpy(str1, whereisX);

    tok1 = strtok_k(whereisX, "x", &saveptr);
    tok2 = strtok_k(NULL, "x", &saveptr);

    if (tok2 == NULL)
    {
        printf("found return 1\n");
        free(str1);
        return 1;
    }
    else
    {
        printf("returning 0\n");
        tok1 = strtok_k(str1, "x", &saveptr);
        tok2 = strtok_k(NULL, "x", &saveptr);

        printf("tok1 is .. %s and tok2 is %s\n", tok1, tok2);

        bW = atoi(tok1);
        bH = atoi(tok2);

        printf("bW is %d and bH is %d\n", bW, bH);
        /* assigning the results to the output */
        *rW = bW;
        *rH = bH;

        printf("rW is %d  rH is %d\n", *rW, *rH);
        printf("tok1 is %s  tok2 is %s\n", tok1, tok2);

        free(str1);
        return 0;
    }
} //end findX

注意区别:您以 完全错误 的方式使用 malloc,您以完全错误的方式使用 printf 格式标识符,您没有 freeing 分配细绳。

我要补充一点,您正在执行两次strtok_r(一次在if 之外,一次在if 内)。两者将返回相同的数据,因为str1whereisX 的副本

然后代码可以简化为:

int findX(char *whereisX, int *rW, int *rH)
{
    printf("entering findx dia is %s\n\n", whereisX);
    char *tok1, *tok2, *saveptr;

    int bW, bH;

    tok1 = strtok_k(whereisX, "x", &saveptr);
    tok2 = strtok_k(NULL, "x", &saveptr);

    if (tok2 == NULL)
    {
        printf("found return 1\n");
        return 1;
    }
    else
    {
        printf("returning 0\n");

        printf("tok1 is .. %s and tok2 is %s\n", tok1, tok2);

        bW = atoi(tok1);
        bH = atoi(tok2);
        printf("bW is %d and bH is %d\n", bW, bH);
        // printf("string -- bW is %s and bH is %s\n", bW,bH);
        /* assigning the results to the output */
        *rW = bW;
        *rH = bH;
        printf("rW is %d  rH is %d\n", *rW, *rH);
        printf("tok1 is %s  tok2 is %s\n", tok1, tok2);
        return 0;
    }
} //end findX

用 C 语言编写的随机程序有时会运行返回看似正确的内容这一事实并不意味着它们是正确的。只能说明你走运了。这种好运不会持久。

【讨论】:

  • 太棒了——最后的评论太棒了——意外地编程。 +1
  • @jimmcnamara 回去看看他关于运气编程的讲座“答案”为我的功能所做的示例——他需要接受自己的建议
  • 你重复了 OP 的 casting malloc 错误。 OP 的代码可以作为反例,让那些认为强制转换 malloc 的缺点之一是它可以隐藏有用的编译器诊断的想法的人嗤之以鼻。
  • @xanatos 你的代码只是把功能搞砸了——在我看来你并没有提出你自己的建议——mods 消除了所有的错误,它让我按照你的方式尝试我在你的帖子中添加的——显示你在哪里错了
  • @WeatherVane char str1[1+strlen(whereisX)]; strcpy(str1, whereisX);解决了我所有的问题,谢谢---
猜你喜欢
  • 2014-07-25
  • 1970-01-01
  • 2011-10-27
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 2015-09-19
  • 2021-01-22
  • 2014-09-11
相关资源
最近更新 更多