C 从表示为字符[]的街道地址解析门牌号

C 从表示为字符[]的街道地址解析门牌号,c,arrays,char,C,Arrays,Char,假设我有一个存储为char[]的街道地址。有效值的示例: 宾夕法尼亚大道1600号 1无限循环 贝克街221号 如你所见,门牌号码可以是任意长度 在C语言中,什么是一种有效的方法将门牌号分隔成自己的整数?我想我需要写一个while循环来检查每个字符c if isdigit,但我不知道在实现方面我是否在正确的轨道上。您可以使用strok将字符串分解为令牌,并使用isdigit来确定该令牌是否为数字 #include <string.h> #include <stdio.h>

假设我有一个存储为char[]的街道地址。有效值的示例:

宾夕法尼亚大道1600号 1无限循环 贝克街221号 如你所见,门牌号码可以是任意长度


在C语言中,什么是一种有效的方法将门牌号分隔成自己的整数?我想我需要写一个while循环来检查每个字符c if isdigit,但我不知道在实现方面我是否在正确的轨道上。

您可以使用strok将字符串分解为令牌,并使用isdigit来确定该令牌是否为数字

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

int main()
{
   const char str1[80] = "1600 Pennsylvania Ave";
   int houseNumber = 0;
   const char s[2] = " ";
   char *token;

   /* get the first token */
   token = strtok(str, s);

   /* walk through other tokens */
   while( token != NULL ) {
      printf( " %s\n", token );
      if (isdigit(str1[0])) {
           houseNumber = atoi (token);
      }
      token = strtok(NULL, s);
   }

   return(0);
}
或者,您可以使用sscanf读取整个字符串并自动解析所有内容:

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

int main()
{
   const char str1[80] = "1600 Pennsylvania Ave";
   int houseNumber = 0;
   char streetName[50];
   char streetExt[20]; 

   sscanf (str1,"%d %s %s", &houseNumber, streetName, streetExt);

   return(0);
}

最后一个方法取决于字符串的格式在所有情况下都完全相同,这意味着它总是一个数字后跟2个字符串。如果有更多的其他东西,strtok方法的容错性会更强。

考虑以下解决方案:

包括 包括 int mainvoid { 字符地址[255]; char*ptr; 整数; 字符序列号[100]; 字符strstret[255]; //询问地址 printfPlease,输入地址:; //将字符串的末尾替换为换行符 fgetsaddress,255,标准DIN; ptr=strchradress,'\n'; ifptr { *ptr='\0'; } 其他的 { 地址[254]=“\0”; } //试着从字符串的开头读取整数 如果1==sscanfaddress,%d,&number { //如果需要,将数字设置为字符串 sprintfstrnumber,%d,number; //把绳子分开 ptr=strchradress+strlenstrnumber',;//查找第一个空格 如果ptr { strcpyStrSet,ptr+1;//+1只是为了跳过找到的空间 } } 其他的 {//如果地址字符串开头没有数字 数字=0; strnumber[0]='\0'; strstreet[0]='\0'; } //显示结果 printfy您输入了一个字符串:\n%s\n,地址; printf找到的号码是:\n%d\n,号码; 打印找到的数字作为字符串:\n%s\n,strnumber; printf没有编号的地址是:\n%s\n,strstrset; }
我会像这样使用strstr和atoi

char someAddress[80] = "1600 Pennsylvania Ave";
char* p = strstr(someAddress, " ");
if (p)
{
    *p = 0;    // Terminate string, i.e. cheat for a moment
    int number = atoi(someAddress);
    *p = " ";  // Restore someAddress
}
else
{
     // Handle illegal format in someAddress
}

只有当您知道在短时间内修改某个地址是安全的时,才可以使用此方法。

这是数字优先的一种情况,在这种情况下,只需使用简单的指针和if语句来解析行就更容易了:

#include <stdio.h>

#define ADDL 64

int main (void) {

    char address[ADDL] = {0};
    char street[16] = {0};

    while (fgets (address, ADDL-1, stdin) != NULL) 
    {
        char *ap = address;
        char *sp = street;

        while (*ap >= '0' && *ap <= '9')  /* while the char is a number */
        {
            *sp = *ap++;                  /* copy to street number      */
            sp++;
        }
        *sp = 0;                          /* null-terminate             */

        printf (" Address: %s Number : %s\n\n", address, street);
    }

    return 0;
}
输出


注意:上面的printf语句使用地址末尾的嵌入换行符,而不是像通常那样剥离它。另外请注意,如果您希望数字为整数、长或无符号,只需在street上调用atoi、strtol或strtoul即可。

考虑使用sscanf@user3386109:我的理解是sscanf仅对预格式化字符[]有用,对吗?不确定预格式化字符[]的含义。sscanf可用于从问题中的字符串中提取前导数字。如果没有前导号,sscanf将返回0。Strtol?斯坎夫?你习惯的任何事情都会奏效;问题是什么?将门牌号存储为整数是否是个好主意也是有争议的。通常,门牌号具有som非数字部分,如165 bis或51/IV,因此字符数组可能是更好的数据类型。毕竟,福尔摩斯的地址是贝克街221B号。
$ ./bin/split_address < dat/houses.txt
 Address: 1600 Pennsylvania Ave
 Number : 1600

 Address: 1 Infinite Loop
 Number : 1

 Address: 221 Baker Street
 Number : 221