在输入文件中搜索并打印所有非重复的结构名称

时间:2015-07-03 08:55:20

标签: c arrays string struct getline

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

/* Search and Print all non-duplicate struct names inside input file */
int main(int argc, char *argv[])
{
        char temp[64], buf[64], filename[128], array[1024] = "";
        char *ptr, *line = NULL;
        char *tmp1, *tmp2;
        ssize_t rv;
        size_t len;
        int count = 0;
        FILE *fp;

        if (argc < 2) {
                printf("enter file name at cmd line...\n");
                return -1;
        }

        sprintf(filename, argv[1], strlen(argv[1]));
        fp = fopen(argv[1], "r");
        if (!fp) {
                printf("File could not be opened: %s\n", argv[1]);
                return -1;
        }

        while ((rv = getline(&line, &len, fp)) != -1) {
                ptr = strstr(line, "struct");
                if (ptr) {
                        ptr += strlen("struct");

                        while (*ptr == ' ')
                                ptr++;

                        tmp1 = strchr(ptr, ' ');
                        tmp2 = strchr(ptr, ';');
                        len = 0;

                        if (tmp1 == NULL && tmp2 == NULL) {
                                continue;
                        }
                        else if (tmp1 == NULL && tmp2 != NULL) {
                                len = tmp2 - ptr;
                        }
                        else if (tmp1 != NULL && tmp2 == NULL) {
                                len = tmp1 - ptr;
                        }
                        else if (tmp1 && tmp2) {
                                len = tmp1 < tmp2 ? tmp1 - ptr : tmp2 - ptr;
                        }

                        if (len) {
                                snprintf(temp, len+1, "%s", ptr);

                                if (!strstr(array, temp)) {
                                        sprintf(buf, "%2d. ", count++);
                                        strcat(buf, temp);
                                        strcat(array, buf);
                                        strcat(array, "\n");
                                }
                        }
                }
        }

        fclose(fp);
        if (line)
                free(line);
        printf("%s\n", array);
        return 0;
}

以上程序正确查找struct个名称,但我在输出名称末尾看到,)等字符。如何删除它?以下是示例输出:

[root@mnm-server programs]# ./a.out /usr/src/linux/drivers/net/ethernet/smsc/smsc911x.c
 0. smsc911x_data
 1. smsc911x_ops
 2. smsc911x_platform_config
 3. phy_device
 4. mii_bus
 5. net_device
 6. napi_struct
 7. regulator_bulk_data
 8. clk
 9. platform_device
10. smsc911x_data,
11. sk_buff
12. net_device_stats
13. netdev_hw_addr
14. sockaddr
15. ethtool_drvinfo
16. ethtool_eeprom
17. ethtool_ops
18. net_device_ops
19. ures,
20. resource
21. device_node
22. smsc911x_data))
23. dev_pm_ops
24. of_device_id
25. platform_driver

注意第10行和第22行的输出。一种方法是对,);执行strchr并从结尾删除char。但是,如果非字母字符的数量增加,这不是一个干净的解决方案。

注意: 我找到的最佳解决方案是here

1 个答案:

答案 0 :(得分:0)

感谢Daniel Jour的输入,以下代码处理struct name* ptr;struct name{ };struct { };

的所有情况
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

/* Search and Print all non-duplicate struct names inside input file */
int main(int argc, char *argv[])
{
        char temp[64], buf[64], filename[128], array[1024] = "";
        char *ptr, *line = NULL;
        size_t len;
        int count = 0, flag = 0;
        FILE *fp;

        if (argc < 2) {
                printf("enter file name at cmd line...\n");
                return EXIT_FAILURE;
        }

        sprintf(filename, argv[1], strlen(argv[1]));
        fp = fopen(argv[1], "r");
        if (!fp) {
                printf("File could not be opened: %s\n", argv[1]);
                return EXIT_FAILURE;
        }

        while ((getline(&line, &len, fp)) != -1) {
                ptr = flag ? line : strstr(line, "struct ");
                if (ptr) {
                        if (!flag)
                                ptr += strlen("struct ");
                        while (*ptr == ' ')
                                ptr++;

                        len = 0;
                        while (isalnum(*ptr) || *ptr == '_' || *ptr == '{' || *ptr == '}') {
                                if (*ptr == '{') {
                                        flag++;
                                }
                                else if (*ptr == '}') {
                                        len = 0;
                                        flag--;
                                        do {
                                                ptr++;
                                        } while (*ptr == ' ');
                                        ptr--;
                                }
                                else if ((*ptr != '{') || (*ptr != '}')) {
                                        len++;
                                }
                                ptr++;
                        }

                        if (len && !flag) {
                                ptr -= len;
                                snprintf(temp, len+1, "%s", ptr);

                                if (!strstr(array, temp)) {
                                        sprintf(buf, "%2d. ", count++);
                                        strcat(buf, temp);
                                        strcat(array, buf);
                                        strcat(array, "\n");
                                }
                        }
                }
        }

        fclose(fp);
        if (line)
                free(line);
        printf("%s\n", array);
        return EXIT_SUCCESS;
}

此程序不处理func(struct x, struct y)等案例,感兴趣的用户可以修复它或只使用grep -o "struct [^ ;,)]\+" # | awk '{print $2}' | sort -upre-processed文件hworld.i的上述程序的输出:

[root@server]# cat hworld.c
#include <stdio.h>

int main()
{
        printf("hello world\n");
        return 0;
}

[root@server]# gcc -Wall --save-temps hworld.c
[root@server]# ./find_structs hworld.i
 0. _IO_FILE
 1. _IO_marker
 2. _IO_FILE_plus