C 将文件中的电话号码转换为新格式

C 将文件中的电话号码转换为新格式,c,io,C,Io,我正在尝试转换一系列以各种方式书写的电话号码,例如: 324.323 4345 234-345-6456. 我想将它们转换成的格式是:(xxx)xxx xxxx 这是我到目前为止的代码,不幸的是它不起作用 #include <stdio.h> #include <stdlib.h> #include <ctype.h> int main() { FILE *fp; char str[31], ch; int i = 0, p1,

我正在尝试转换一系列以各种方式书写的电话号码,例如:

324.323 4345
234-345-6456.
我想将它们转换成的格式是:
(xxx)xxx xxxx

这是我到目前为止的代码,不幸的是它不起作用

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int main() {

    FILE *fp;
    char str[31], ch;
    int i = 0, p1, p2, p3;
    fp = fopen("numbers.txt", "r");


        while((ch = getc(fp)) != '\n')
       {
 if(isdigit(ch))
                str[i++] = ch;
        str[i] = '\0';
        i = 0;

        sscanf(str, "%3d%3d%4d", &p1, &p2, &p3);
        printf("(%3d) %3d-%4d\n", p1, p2, p3);
      }
fclose(fp);
    return 0;
}
并得到以下结果:

(  4) 4196261-32767
(  0) 4196261-32767
(  4) 4196261-32767
(  4) 4196261-32767
(  8) 4196261-32767
(  1) 4196261-32767
(  7) 4196261-32767
(  7) 4196261-32767
(  6) 4196261-32767
(  9) 4196261-32767
(  0) 4196261-32767
(  0) 4196261-32767
(  0) 4196261-32767

我可能会从以下内容开始:

if (3 == sscanf(str, "%3d%*[^0-9]%3d%8[^0-9]%4d", &p1, &p2, &p3))
    printf("(%3d) %3d-%4d\n", p1, p2, p3);
int copy_num(FILE *file, FILE *out) { 
    char p1[4], p2[4], p3[5];
    int ret=0;

    fscanf(file, "%*[^0-9]");
    ret += fscanf(file, "%3s%*[^0-9]", p1);
    ret += fscanf(file, "%3s%*[^0-9]", p2);
    ret += fscanf(file, "%4s", p3);
    if (ret == 3)
        fprintf(out, "(%3s) %3s-%4s\n", p1, p2, p3);
    return ret == 3;
}
“%*[^0-9]”部分跳过任何其他部分,直到到达下一个数字

编辑:我没有注意到其中一个可能的输入在数字之间根本没有分隔。不幸的是,您不能将scanf的整数转换限制为只读取前三位数字或类似的内容。要解决这个问题,您几乎需要读取字符串而不是数字。为了让代码更易于理解,我还将代码分成几部分,而不是试图一次阅读所有代码,给出如下内容:

if (3 == sscanf(str, "%3d%*[^0-9]%3d%8[^0-9]%4d", &p1, &p2, &p3))
    printf("(%3d) %3d-%4d\n", p1, p2, p3);
int copy_num(FILE *file, FILE *out) { 
    char p1[4], p2[4], p3[5];
    int ret=0;

    fscanf(file, "%*[^0-9]");
    ret += fscanf(file, "%3s%*[^0-9]", p1);
    ret += fscanf(file, "%3s%*[^0-9]", p2);
    ret += fscanf(file, "%4s", p3);
    if (ret == 3)
        fprintf(out, "(%3s) %3s-%4s\n", p1, p2, p3);
    return ret == 3;
}

我可能会从以下内容开始:

if (3 == sscanf(str, "%3d%*[^0-9]%3d%8[^0-9]%4d", &p1, &p2, &p3))
    printf("(%3d) %3d-%4d\n", p1, p2, p3);
int copy_num(FILE *file, FILE *out) { 
    char p1[4], p2[4], p3[5];
    int ret=0;

    fscanf(file, "%*[^0-9]");
    ret += fscanf(file, "%3s%*[^0-9]", p1);
    ret += fscanf(file, "%3s%*[^0-9]", p2);
    ret += fscanf(file, "%4s", p3);
    if (ret == 3)
        fprintf(out, "(%3s) %3s-%4s\n", p1, p2, p3);
    return ret == 3;
}
“%*[^0-9]”部分跳过任何其他部分,直到到达下一个数字

编辑:我没有注意到其中一个可能的输入在数字之间根本没有分隔。不幸的是,您不能将scanf的整数转换限制为只读取前三位数字或类似的内容。要解决这个问题,您几乎需要读取字符串而不是数字。为了让代码更易于理解,我还将代码分成几部分,而不是试图一次阅读所有代码,给出如下内容:

if (3 == sscanf(str, "%3d%*[^0-9]%3d%8[^0-9]%4d", &p1, &p2, &p3))
    printf("(%3d) %3d-%4d\n", p1, p2, p3);
int copy_num(FILE *file, FILE *out) { 
    char p1[4], p2[4], p3[5];
    int ret=0;

    fscanf(file, "%*[^0-9]");
    ret += fscanf(file, "%3s%*[^0-9]", p1);
    ret += fscanf(file, "%3s%*[^0-9]", p2);
    ret += fscanf(file, "%4s", p3);
    if (ret == 3)
        fprintf(out, "(%3s) %3s-%4s\n", p1, p2, p3);
    return ret == 3;
}

这对你有用吗?可以说,它在樱桃上咬了三口(在最坏的情况下):


这对你有用吗?可以说,它在樱桃上咬了三口(在最坏的情况下):

以下代码

NBPhoneNumberUtil *phoneUtil = [NBPhoneNumberUtil sharedInstance];

NSError *aError = nil;
NBPhoneNumber *myNumber = 
    [phoneUtil parse:@"6766077303" defaultRegion:@"AT" error:&aError];

if (aError == nil) {
    // Should check error
    NSLog(@"isValidPhoneNumber ? [%@]", 
        [phoneUtil isValidNumber:myNumber] ? @"YES":@"NO");
    NSLog(@"E164          : %@", [phoneUtil format:myNumber 
                                      numberFormat:NBEPhoneNumberFormatE164 
                                             error:&aError]);
    NSLog(@"INTERNATIONAL : %@", [phoneUtil format:myNumber
                                      numberFormat:NBEPhoneNumberFormatINTERNATIONAL 
                                             error:&aError]);
    NSLog(@"NATIONAL      : %@", [phoneUtil format:myNumber 
                                      numberFormat:NBEPhoneNumberFormatNATIONAL 
                                             error:&aError]);
    NSLog(@"RFC3966       : %@", [phoneUtil format:myNumber  
                                      numberFormat:NBEPhoneNumberFormatRFC3966 
                                             error:&aError]);
}
else {
    NSLog(@"Error : %@", [aError localizedDescription]);
}
我会退还的

isValidPhoneNumber ? [YES]
E164          : +436766077303
INTERNATIONAL : +43 676 6077303
NATIONAL      : 0676 6077303
RFC3966       : tel:+43-676-6077303

以下代码

NBPhoneNumberUtil *phoneUtil = [NBPhoneNumberUtil sharedInstance];

NSError *aError = nil;
NBPhoneNumber *myNumber = 
    [phoneUtil parse:@"6766077303" defaultRegion:@"AT" error:&aError];

if (aError == nil) {
    // Should check error
    NSLog(@"isValidPhoneNumber ? [%@]", 
        [phoneUtil isValidNumber:myNumber] ? @"YES":@"NO");
    NSLog(@"E164          : %@", [phoneUtil format:myNumber 
                                      numberFormat:NBEPhoneNumberFormatE164 
                                             error:&aError]);
    NSLog(@"INTERNATIONAL : %@", [phoneUtil format:myNumber
                                      numberFormat:NBEPhoneNumberFormatINTERNATIONAL 
                                             error:&aError]);
    NSLog(@"NATIONAL      : %@", [phoneUtil format:myNumber 
                                      numberFormat:NBEPhoneNumberFormatNATIONAL 
                                             error:&aError]);
    NSLog(@"RFC3966       : %@", [phoneUtil format:myNumber  
                                      numberFormat:NBEPhoneNumberFormatRFC3966 
                                             error:&aError]);
}
else {
    NSLog(@"Error : %@", [aError localizedDescription]);
}
我会退还的

isValidPhoneNumber ? [YES]
E164          : +436766077303
INTERNATIONAL : +43 676 6077303
NATIONAL      : 0676 6077303
RFC3966       : tel:+43-676-6077303

它以什么方式不起作用?有什么问题吗?对于一个包含两行输入且没有前导/尾随字符的文件,它可以工作(linux)。@MichaelFoukarakis它运行,但是它不能显示正确的内容。它以什么方式不工作?有什么问题吗?对于一个包含两行输入且没有前导/尾随字符的文件,它可以工作(linux)。@MichaelFoukarakis它运行,但是它没有显示正确的内容。3来自哪里?大概你是指
if中的
3
(3==…
sscanf
的返回值是它成功转换的字段数,因此这是在检查我们要求它转换的三个字段是否都已成功转换。我将其放在我拥有的代码中,现在它根本不打印任何内容。@user1855131:Oops——愚蠢的输入错误(“%8”在我想要的“%*”)
sscanf(buffer,“%*[^0-9]%3d%*[^0-9]%3d%*[^0-9]%4d”、&p1、&p2、&p3);
至少会好一点,但在最后一个示例中,如果数字都混在一起,它仍然不起作用。要解决这个问题,您只需要读取字符串而不是int。我应该如何/在哪里使用
if(3==sscanf
如果我替换了我目前拥有的东西,它不会起任何作用。谢谢,我只是想更好地了解怎么做。3是从哪里来的?你大概是指
if中的
3
(3==…
sscanf
的返回值是它成功转换的字段数,因此这是在检查我们要求它转换的三个字段是否都已成功转换。我将其放在我拥有的代码中,现在它根本不打印任何内容。@user1855131:Oops——愚蠢的输入错误(“%8”在我想要的“%*”)
sscanf(buffer,“%*[^0-9]%3d%*[^0-9]%3d%*[^0-9]%4d”、&p1、&p2、&p3);
至少会好一点,但在最后一个示例中,如果数字都混在一起,它仍然不起作用。要解决这个问题,您只需要读取字符串而不是int。我应该如何/在哪里使用
if(3==sscanf
如果我替换了我目前拥有的东西,它不会起任何作用。谢谢,我只是想更好地了解如何做到这一点。很酷,但是你如何让它从文件中读取而不是让用户输入它呢?我使用了
/x
,所以程序从作为标准输入的文件中读取它。我当然这样做了不要键入数据(long-live copy'n'paste)。使用您的程序作为基础,我会像您一样打开文件,检查它是否工作(您不这样做,但应该这样做),然后简单地将
fgets(buffer,sizeof(buffer),stdin)
替换为
fgets(buffer,sizeof(buffer),fp)
;循环的其余部分将保持不变(除非您决定停止打印输入缓冲区)。很酷,但是您如何让它从文件中读取而不是让用户输入它呢?我使用了
/x
,所以程序从作为标准输入的文件中读取它。我当然没有键入您的数据(long live copy'n'paste).使用您的程序作为基础,我会像您一样打开文件,检查它是否工作(您不这样做,但应该这样做),然后简单地将
fgets(buffer,sizeof(buffer),stdin)
替换为
fgets(buffer,sizeof(buffer),fp)
;我循环的其余部分将保持不变(除非您决定停止打印输入缓冲区)。