【问题标题】:Need help for int args (threads)需要有关 int args(线程)的帮助
【发布时间】:2014-12-29 05:58:04
【问题描述】:

我正在尝试编辑此代码以使用 ints 参数:

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


void* worker (void* param) {
      int* nr = (int *) param;
  printf ("I got: %d\n",nr);
}

int main (int argc, int *argv[])
{
  pthread_t th;
  int i;  
  for(i=1;i<argc;i++){
      pthread_create (&th, NULL, worker,(void*)argv[i]);
      pthread_join (th, NULL);
  }
}

这不起作用,关于指针的smth,我不明白。谁能解释我?我不想使用“atoi”功能。 对于数字 5 和 2,我得到:-1078000975,-1078000973 和警告:

11:3:警告:格式“%d”需要“int”类型的参数,但参数 2 的类型为“int *”[-Wformat=] printf ("我得到了: %d\n", nr); ^

【问题讨论】:

  • int nr = *(int *)param
  • 代码为每个创建的线程覆盖了 'th' 中的值,因此 pthread_join 只会看到最后创建的线程,而不是所有线程

标签: c pointers pthreads args


【解决方案1】:

如果您收到的参数小于 10,您可以这样做:

pthread_create (&amp;th, NULL, worker,(void*)(argv[i][0]-'0'));

这是可以做到的,因为 ASCII 数字从 48('0' 值)开始。所以如果你收到一个'7'(55个ASCII码),你可以减去'0'得到它:55-48=7。 如果参数可以是 10 或更大,则必须使用 atoi 或该函数的自实现,因为您不能在 C 中从 char* 转换为 int。

您的代码还有另一个问题,您尝试打印一个 int*,它只是一个包含内存地址的变量。您应该将其作为 int 接收:

void* worker (void* param)
{
  int nr = (int) param;
  printf ("I got: %d\n",nr);
}

编辑: 所以你的代码应该是这样的:

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


void* worker (void* param) {
      int nr = (int) param;
  printf ("I got: %d\n",nr);
}

int main (int argc, char *argv[])
{
  pthread_t th;
  int i;  
  for(i=1;i<argc;i++){
      pthread_create (&th, NULL, worker,(void*)(argv[i][0]-'0'));
      pthread_join (th, NULL);
  }
}

它对我有用...

【讨论】:

    【解决方案2】:

    几个问题:

    1. argv 应该写成char * argv[],而不是int * argv[]

    2. 您的(void *) 不需要在您的pthread_create() 调用中进行转换。

    3. 你的线程函数应该返回一个void *

    4. atoi(),或者它更能干的表亲strtol(),正是正是你正在寻找的,在这里。您可以使用它们,也可以手动转换字符串,这是次优的。

    这是一个工作版本:

    #include <stdio.h> 
    #include <stdlib.h> 
    #include <pthread.h> 
    
    void * worker (void * param)
    {
        char * numstr = param, * endptr;
    
        long num = strtol(numstr, &endptr, 0);
        if ( *endptr ) {
            printf("Invalid number.\n");
        }
        else {
            printf ("I got: %ld\n", num);
        }
    
        return NULL;
    }
    
    int main (int argc, char *argv[])
    {
        pthread_t th;
        for ( int i = 1; i < argc; ++i ) {
            pthread_create (&th, NULL, worker, argv[i]);
            pthread_join (th, NULL);
        }
        return 0;
    }
    

    还有一些示例输出:

    paul@horus:~/src/sandbox$ ./trd 5 haha 10
    I got: 5
    Invalid number.
    I got: 10
    paul@horus:~/src/sandbox$
    

    【讨论】:

      【解决方案3】:

      您应该将指针传递给字符串,然后对其进行操作。

      pthread_create (&th, NULL, worker, argv[i]);   //cast is not required
      
      void* worker (void* param) {
            char* nr = param ;
      

      现在你在线程中得到了你的字符串。获取第一个字符,并将其转换为整数。

          int n = nr[0]-'0' ;
          printf ("I got: %d\n",n);
      }
      

      【讨论】:

      • @AlbertoSotoBallesteros 对,我忘了转换。
      • 建议的代码需要遍历字符串,直到看到 '\0' 或当前字符失败 isdigit() 否则只会处理第一个数字。在将每个连续数字添加到要打印的结果之前,需要将“n”乘以 10,以便为下一个数字腾出空间
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-23
      • 2014-12-26
      • 2013-08-12
      相关资源
      最近更新 更多