号码归属地系统(二)

文摘   2024-10-19 00:01   安徽  
接着号码归属地系统(一),这里设计数据读入模块,从外部文件(txt文档)读取号码段与归属地信息,并将其存储在内存的数据结构中。

1、文档格式

这里涉及字节顺序问题,即多字节数据在内存中的存储顺序。Little-Endian(小端字节序),即低内存地址存放低位字节,高内存地址存放高位字节;与之相反的是,Big-Endian(大端字序),即低内存地址存放高位字节,高内存地址存放低位字节。如“10”分别存储为utf-16le和utf-16be,存储字节顺序如下图所示。

因在Windows平台下默认采用的是小端字节序(little-endian),所以这里的文档采用UTF-16LE编码。另外,文档还涉及BOM(字节顺序标记),可以检查文件是UTF-16 LE(头两个字节为fffe)还是UTF-16 BE(头两个字节为feff
文档数据内容编码格式为,“号码{Tab键或空格等其他间隔符}地址”,如“10    北京“。
2、读取数据

读取每行数据,并解析为号码和地址,分别打印。

#include <stdio.h>#include <wchar.h>#include <locale.h>void readline(FILE *file);int main(){    //设置区域,支持宽字符    setlocale(LC_CTYPE, "");    FILE *file = fopen("location.txt", "rb");//UTF-16LE,以二进制格式只读打开    if (file == NULL) {        wprintf(L"Error opening file.\n");        return 1;    }    fseek(file,2L,SEEK_CUR);//跳过两字节,BOM    readline(file);//调用    fclose(file);// Close the file
return 0;}
void readline(FILE *file){ wchar_t buffer[256];//存储每行数据 int number;//存储号码 wchar_t address[256];//存储地址
//遍历每行,并输出 while (fgetws(buffer, 256, file) != NULL) {        // 解析行数据,tab间隔符 if (swscanf(buffer, L"%d\t%ls",&number, address) == 2) { //打印每行数据 wprintf(L"No: %d, Address: %ls\n", number, address); } else { wprintf(L"Error parsing line: %ls\n", buffer); } }}
运行结果如下,

3、构建数据链表

定义数据结构,如下。
typedef struct Node{  int number;//号码  wchar_t address[256];//地址  struct Node * pNext;}NODE, * PNODE;
调整上述函数,构建数据链表,并打印。
#include <stdio.h>#include <wchar.h>#include <locale.h>
typedef struct Node{ int number;//号码 wchar_t address[256];//地址 struct Node * pNext;}NODE, * PNODE;
void readline(FILE *file,PNODE *pHead);int iniList(PNODE *pHead,FILE *file);void printList(PNODE pHead);

int main(){ //设置区域,支持宽字符 setlocale(LC_CTYPE, ""); FILE *file = fopen("location.txt", "rb");//UTF-16LE,以二进制格式只读打开 if (file == NULL) { wprintf(L"Error opening file.\n"); return 1; } fseek(file,2L,SEEK_CUR);//跳过两字节,BOM PNODE pHead; readline(file,&pHead);//调用 fclose(file);// Close the file
wprintf(L"===============================================\n"); printList(pHead);
return 0;}

void readline(FILE *file, PNODE *pHead){ wchar_t buffer[256];//存储每行数据 //int number;//存储号码 //wchar_t address[256];//存储地址
*pHead =(PNODE)malloc(sizeof(NODE)); if (!pHead) { wprintf(L"Error malloc\n"); return; } (*pHead)->number=0; memset((*pHead)->address,0,256); (*pHead)->pNext=NULL; PNODE pnail = *pHead; PNODE pnew;
//遍历每行,并输出 while (fgetws(buffer, 256, file) != NULL) { pnew=(PNODE)malloc(sizeof(NODE)); if (!pnew) { wprintf(L"Error malloc\n"); return; } // 解析行数据,tab间隔符 if (swscanf(buffer, L"%d\t%ls",&(pnew->number),pnew->address) == 2) {
//wprintf(L"No: %d, Address: %ls\n", pnew->number, pnew->address); pnail->pNext=pnew; pnail=pnew; pnail->pNext=NULL; pnew=NULL; } else { wprintf(L"Error parsing line: %ls\n", buffer); } } pnew = *pHead; free(pnew); *pHead=(*pHead)->pNext;}
void printList(PNODE pHead){ PNODE p; while(pHead!=NULL) { p=pHead; //打印数据 wprintf(L"No: %d, Address: %ls\n", p->number, p->address); pHead=pHead->pNext; free(p); }}

知行悟传
个人学习、工作经验记录和分享。如果对您有帮助,感谢帮忙关注、转发和宣传。