C 为什么我的atoi功能不工作?

C 为什么我的atoi功能不工作?,c,atoi,C,Atoi,我试图创建我的个人atoi函数,但我没有正常工作。我不知道为什么 void ft_putchar(char c) { write(1, &c, 1); } int ft_atoi(const char *str) { int i; i = 0; while (str[i] == 9 || str[i] == 32 || str[i] == 43 || str[i] == 45) i++; while (str[i] > 4

我试图创建我的个人atoi函数,但我没有正常工作。我不知道为什么

void ft_putchar(char c)
{
    write(1, &c, 1);
}

int ft_atoi(const char *str)
{
    int i;

    i = 0;
    while (str[i] == 9 || str[i] == 32 || str[i] == 43 || str[i] == 45)
        i++;
    while (str[i] > 48 && str[i] < 57)
    {
        ft_putchar(str[i]);
        i++;
    }
    return (0); 
}

int main(void)
{
    printf("%d", atoi("     2794ffafsaasf"));
    printf("\n%d",ft_atoi("     2794fsffsf"));

    return(0);
}
只使用我的函数,它只给我数字
27

编辑:

我创建了一个新程序。但它仍然不起作用。它根本看不到数字

int ft_atoi(const char *str)
{
    int i;
    int n;

    i = 0;
    while (str[i] == '\t' || str[i] == ' ' || str[i] == '+' || str[i] == '-')
        ++i;
    n = i;
    while (str[n] >= '0' && str[n] <= '9')
    {
            ++n;
    }
    return(str[n]);
}
int ft_原子(常量字符*str)
{
int i;
int n;
i=0;
而(str[i]='\t'| | str[i]='''| | str[i]='+'| | str[i]='-')
++一,;
n=i;

而(str[n]>='0'&&str[n]您的数字测试的边界设置错误。您正在测试
str[i]>48&&str[i]< 57 < /代码>,但48是“代码>0”/代码>字符的序号,57是“代码> 9 < /COD>的序号。这意味着您只考虑1到8包含数字位数,并且在<代码> 9 中停止解析<代码> 2904FSFFSF < /代码>,而不是在第一个<代码> f>代码> < < /P>

将测试更改为
str[i]>=48&&str[i]数字测试的边界设置错误。您正在测试
str[i]>48&&str[i]< 57 < /代码>,但48是“代码>0”/代码>字符的序号,57是“代码> 9 < /COD>的序号。这意味着您只考虑1到8包含数字位数,并且在<代码> 9 中停止解析<代码> 2904FSFFSF < /代码>,而不是在第一个<代码> f>代码> < < /P>

将测试更改为
str[i]>=48&&str[i]第一件事是忽略前导空格。您可以在执行时使用
i
,但通过向前移动字符串的开头更容易做到。我猜您是在重新实现标准C库作为练习。我没有,所以我将使用.Adjust as You like,基本代码保持不变。Y您可能应该编写自己的
ft\u isspace
ft\u isdigit
而不是硬编码逻辑

/* Move str to point at the first non-space character */
while( isspace(str[0]) ) {
    str++;
}
现在不需要使用
i
来代替您的位置,您只需使用
str[0]
即可,它将是第一个非空白字符


下一步我们需要找到并加上我们的数字。同样,我将使用
isdigit
。如果您不能使用该函数,请遵循

技术是将每个字符转换成一个数字,并将其加到总数中。因为我们从左到右读取一个数字,每个新的数字将现有的总和乘以10。例如,如果我们有1234,它将是…1,然后是10+2,然后是120+3,然后是1230+4

int num = 0;
while( isdigit(str[0]) ) {
    int digit = str[0] - '0';
    num *= 10;
    num += digit;

    str++;
}
我再次操作指针,而不是使用索引。这只是为了保存一个整数,并避免在单个函数中混淆两种字符串迭代技术

最后,别忘了返回号码

return num;

负数呢?在检查数字之前,我们需要查找
-
,如果有,请翻转符号。我们还需要处理
+
并忽略它

/* Assume it's positive. */
short sign = 1;

/* Check for a sign. */
switch( str[0] ) {
    case '-':
        sign = -1;
        str++;
        break;
    case '+':
        str++;
        break;
}
然后乘以该符号以翻转结果

return sign * num;

第一件事是忽略前导空格。你可以在做的时候用
i
这样做,但是通过向前移动字符串的开头更容易做到。我猜你是在练习重新实现标准C库。我不是,所以我要使用。根据你的喜好调整,基本代码保持不变。哟您可能应该编写自己的
ft\u isspace
ft\u isdigit
而不是硬编码逻辑

/* Move str to point at the first non-space character */
while( isspace(str[0]) ) {
    str++;
}
现在不需要使用
i
来代替您的位置,您只需使用
str[0]
即可,它将是第一个非空白字符


下一步我们需要找到并加上我们的数字。同样,我将使用
isdigit
。如果您不能使用该函数,请遵循

技术是将每个字符转换成一个数字,并将其加到总数中。因为我们从左到右读取一个数字,每个新的数字将现有的总和乘以10。例如,如果我们有1234,它将是…1,然后是10+2,然后是120+3,然后是1230+4

int num = 0;
while( isdigit(str[0]) ) {
    int digit = str[0] - '0';
    num *= 10;
    num += digit;

    str++;
}
我再次操作指针,而不是使用索引。这只是为了保存一个整数,并避免在单个函数中混淆两种字符串迭代技术

最后,别忘了返回号码

return num;

负数呢?在检查数字之前,我们需要查找
-
,如果有,请翻转符号。我们还需要处理
+
并忽略它

/* Assume it's positive. */
short sign = 1;

/* Check for a sign. */
switch( str[0] ) {
    case '-':
        sign = -1;
        str++;
        break;
    case '+':
        str++;
        break;
}
然后乘以该符号以翻转结果

return sign * num;

您的代码只将数字写入由
1
标识的文件(可能是标准输出,我记不清了……),而不是我前面指出的全部数字(因为它不包括
'0'
'9'
,它们应该包括在内!),并返回
0
作为
printf
的参数。我觉得有点奇怪,您的函数只打印了27个,但它可能是特定于环境(?)的。(我没有测试过它,所以它可能不像我想象的那样工作…)

我已经制作了我的atoi版本,希望我能展示从哪里开始/你应该如何做你的:

int nvi9_atoi(const char *s) {
  int n = 0, valid = 0, prev = 0;
  while(1) {                         // infinite loop
    if (*s == '\0') break;           // if it is the end of the string, finish further processing
    if (*s >= '0' && *s <= '9') {    // check whether the current character is an ascii number
      n *= 10;                       // "move" all previous digits (eg. 1 -> 10, 43 -> 430); if n is 0, this has no effect
      if (n >= 0) n += (*s - '0');   // if n is not negative, add the value of the last digit (here is ascii-number "conversion"!)
      else n -= (*s - '0');          // if it is negative, the number should be substracted (note eg. if there was -10 so far, and the new number is 2, the new value should be -12, not -8)
      if (n > 0 && !valid) {         // if n not 0, and there was no digits before it, check if there was a minus sign before
        valid = 1;                   // preventing more check
        if (prev == '-') n *= -1;    // makes n negative
      }
    } else if (valid) break;         // if there was numbers processed, but the current character is not a number, finish loop
    prev = *s;                       // store current character for minus sign checking of next loop
    s++;                             // move string pointer to the next character
  }
  return n;                          // return the converted value
}
int nvi9_原子(常量字符*s){
int n=0,valid=0,prev=0;
而(1){//无限循环
if(*s=='\0')break;//如果它是字符串的结尾,请完成进一步的处理
如果(*s>='0'&&*s10,43->430);如果n为0,则不起作用
如果(n>=0)n+=(*s-'0');//如果n不是负数,则添加最后一位的值(这里是ascii数字“转换”!)
else n-=(*s-'0');//如果为负数,则应减去该数字(注意,例如,如果到目前为止有-10,而新数字为2,则新值应为-12,而不是-8)
如果(n>0&&!valid){//如果n不是0,并且前面没有数字,请检查前面是否有减号
valid=1;//防止再次检查
如果(prev='-')n*=-1;//使n为负
}
}否则,如果(有效)中断;