读取简单数据声明并以分配给该变量的内存量响应的程序

Posted

技术标签:

【中文标题】读取简单数据声明并以分配给该变量的内存量响应的程序【英文标题】:a program that reads simple data declarations and responds with the amount of memory that would be allocated to that variable 【发布时间】:2017-06-01 06:14:07 【问题描述】:

每个输入行应包含 - 类型名称,必须是以下之一:char、int、short、long、float 或 double。 - 一个或多个单独的声明规范,以逗号分隔。 - 分号标记行尾。

如果读取到空白输入行,程序应该退出。

我为这个程序编写了以下代码。它似乎运作良好,除了我收到以下警告:

d:\documents\documents\visual studio 2012\projects\project3\project3\source.c(108): 警告 C4715: 'theSizeOf' : 并非所有控制路径都返回值。

顺便问一下,我想知道它是否可以改进(可能通过使用 strtok?)。我还想在这个程序中添加一个包含输出的文件,但我完全不确定它是如何完成的。

#define _CRT_SECURE_NO_WARNINGS

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

void bytesPerValue(char str[]);
int theSizeOf(char *str);
 int strToNumber(char *str);

void main()

     char str[50];
     gets(str);

     bytesPerValue(str);



void bytesPerValue(char str[]) //Ex5

        int i = 0, j = 0;
        int temp = 1;
        int size;
        char* tempChar = (char*)malloc((strlen(str))*sizeof(tempChar));
        while (!isspace(str[i]) || str[i]=='*') //checking the type of the variables
        
                tempChar[j] = str[i];
                i++;
                j++;   
        
        tempChar[j] = '\0';
        size = theSizeOf(tempChar);
        j = 0;
        i++;
        while (str[i] != ';')
        

                if (isalpha(str[i]) || str[i]=='_') // for normal variables and arrays
                
                        while (str[i] != ',' && str[i] != ';') //runs until ', ' or '; '
                        
                                if (isspace(str[i]))
                                
                                        while (isspace(str[i]))
                                                i++;
                                

                                if (str[i] == '[') //checks if it is array
                                
                                        printf("%c", str[i]);
                                        i++;
                                        while (str[i] != ']')
                                        
                                                tempChar[j] = str[i]; //copies the value in the string
                                                i++;
                                                j++;
                                        

                                        tempChar[j] = '\0';
                                        temp = strToNumber(tempChar); //converting to number so I can valuate the bytes
                                
                                printf("%c", str[i]);
                                i++;

                                if (isspace(str[i]))
                                
                                        while (isspace(str[i]))
                                                i++;
                                
                        
                        printf(" requires %d bytes \n", temp*size);
                


                if (str[i] == '*') //for pointers
                
                        while (str[i] != ',' && str[i] != ';')
                        
                                printf("%c", str[i]);
                                i++;
                                if (isspace(str[i]))
                                
                                        while (isspace(str[i]))
                                                i++;
                                
                        
                        printf(" requires %d bytes \n", 4);
                
                if (str[i] != ';')
                        i++;
        




int theSizeOf(char* str) // checking the size of the variable

        if (strcmp(str, "int")==0 || strcmp(str, "long")==0 || strcmp(str, "float")==0)
                return 4;
        if (strcmp(str, "char")==0)
                return 1;
        if (strcmp(str, "double")==0)
                return 8;
        if (strcmp(str, "short")==0)
                return 2;



int strToNumber(char* str) //converting the string to number

        int temp=1;
        int num=0;
        int t;
        int i;
        int length = strlen(str);
        for (i = length-1; i >= 0; i--)
        
                t = str[i] - '0';
                num += t * temp;
                temp *= 10;
        
        return num;

【问题讨论】:

I wrote the following code for this program. It seems to work well,...那么,我的朋友,你应该改成Code Review 请提出一个有具体问题的问题。请参阅How to Ask 页面以供参考。谢谢。 如果读取到空白输入行,程序应该退出:在这种情况下,while (!isspace(str[i]) || str[i]=='*') (str[0] == '\0') 它超出了有效范围。 其他部分也有问题。 'theSizeOf' : 不是所有的控制路径都返回一个值。 如果没有对应的类型,返回的值是未定义的。 【参考方案1】:

正如 Sourav Ghosh 提到的,这绝对是代码审查的帖子。 但是由于您已经浪费了时间在这里发帖,我建议您阅读以下内容:

Please explain the output of sizeof()

当您可以使用 sizeof 操作符来完成您的功能正在做的事情时,我不太确定您为什么要定义自己的函数。

编辑:

Another good example

Edint 2.0:你得到的警告基本上是编译器说,“如果你的两个案例都不匹配会发生什么?”。用更简单的话来说,它要求在没有一个 if 与 case 匹配的情况下使用 else case。

关于如何将值写入文件,可以使用 fprintf();

FILE *f = fopen("file.txt", "w");
 if (f == NULL)

  printf("Error opening file!\n");
  exit(1);

int i = 1;
fprintf(f,"%d", i);
fclose(f);

More information and examples for fprintf

【讨论】:

但是如果我使用 sizeof 我得到一个错误的输出(我已经在我的代码中检查过) 你能举个例子说明你是如何使用它的,它返回了什么,你期望什么? 其实这里唯一错误的值是char值,指针cprt应该是4,在数组中caaray[]是假设是 80,但由于 char 是 4,所以它是 320。您在代码中使用结构吗,请提供您检查 sizeof 运算符如何工作的代码。在我这边刚刚返回 sizeof(char) = 1; sizeof(char*point) = 4; sizeof(char[80]) = 80; 我没有在我的代码中使用结构...我真的不明白我的代码出了什么问题.. 我知道 sizeof 操作符是怎么错的,并且得到 sizeof(char) 的输出 1【参考方案2】:

我使用 sizeof 更改了我的代码,但输出错误。

#define _CRT_SECURE_NO_WARNINGS

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

void bytesPerValue(char str[]);
 int strToNumber(char *str);

void main()

     char str[50];
                        gets(str);

                        bytesPerValue(str);



void bytesPerValue(char str[]) 

        int i = 0, j = 0;
        int temp = 1;
        int size;
        char* tempChar = (char*)malloc((strlen(str))*sizeof(tempChar));
        while (str[i]!=' ' || str[i]=='*') //checking the type of the variables//
        
                tempChar[j] = str[i];
                i++;
                j++;   
        
        tempChar[j] = '\0';
        size = sizeof(tempChar);
        j = 0;
        i++;
        while (str[i] != ';')
        

                if (isalpha(str[i]) || str[i]=='_') // for  variables and arrays//
                
                        while (str[i] != ',' && str[i] != ';') //runs until ', ' or '; ' //
                        
                                if (str[i]==' ')
                                
                                        while (str[i]==' ')
                                                i++;
                                

                                if (str[i] == '[') //checks if it is array//
                                
                                        printf("%c", str[i]);
                                        i++;
                                        while (str[i] != ']')
                                        
                                                tempChar[j] = str[i]; //copies the value in the string//
                                                i++;
                                                j++;
                                        

                                        tempChar[j] = '\0';
                                        temp = strToNumber(tempChar); //converting to number in order to valuate the bytes//
                                
                                printf("%c", str[i]);
                                i++;

                                if (isspace(str[i]))
                                
                                        while (isspace(str[i]))
                                                i++;
                                
                        
                        printf(" requires %d bytes \n", temp*size);
                


                if (str[i] == '*') //for pointers//
                
                        while (str[i] != ',' && str[i] != ';')
                        
                                printf("%c", str[i]);
                                i++;
                                if (str[i]==' ')
                                
                                        while (str[i]==' ')
                                                i++;
                                
                        
                        printf(" requires %d bytes \n", 4);
                
                if (str[i] != ';')
                        i++;
        



例如,对于以下输入:char c, *cprt, carray[80]; 我得到以下输出: c 需要 4 个字节 *cprt 需要 4 个字节 caaray[] 需要 320 字节

错了……

【讨论】:

size = sizeof(tempChar); : sizeof(tempChar) 是指针 (tempChar) 大小。您需要解析类型大小。 我该怎么做? 你退出了之前的方法。解析、验证和评估。顺便说一句,您接受 2D-Array 或更多吗? 对不起,我不明白你的回答......我不接受二维数组或更多。 从简单的方法到精确的方法,思维方式多种多样。所以根本不能肯定“Do it like this”。顺便说一句,您接受双指针或更多吗? (如char **strp;【参考方案3】:

我刚刚编辑了我的代码,没有使用 sizeof。我还在我的代码中添加了对文件的使用。我认为它现在运作良好。如果你能告诉我你的想法,我会很高兴,我的代码是应该改进还是修复。

#define _CRT_SECURE_NO_WARNINGS

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

void bytesPerValue(char str[], char* filename) ;
int theSizeOf(char *str);
 int strToNumber(char *str);

void main()

     char str[50];

     gets(str);

     bytesPerValue(str,"input.txt");



void bytesPerValue(char str[], char* filename) 

        int i = 0, j = 0;
        int temp = 1;
        int size;
        char* tempChar = (char*)malloc((strlen(str))*sizeof(tempChar));
        FILE *f=fopen(filename,"w");
        if (f==NULL)
            exit(1);
        while (str[i]!=' ' || str[i]=='*') //checking the type of the variables//
        
                tempChar[j] = str[i];
                i++;
                j++;   
        
        tempChar[j] = '\0';
        size = theSizeOf(tempChar);
        j = 0;
        i++;
        while (str[i] != ';')
        

                if (isalpha(str[i]) || str[i]=='_') // for  variables and arrays//
                
                        while (str[i] != ',' && str[i] != ';') //runs until ', ' or '; ' //
                        
                                if (str[i]==' ')
                                
                                        while (str[i]==' ')
                                                i++;
                                

                                if (str[i] == '[') //checks if it is array//
                                
                                        printf("%c", str[i]);
                                        i++;
                                        while (str[i] != ']')
                                        
                                                tempChar[j] = str[i]; //copies the value in the string//
                                                i++;
                                                j++;
                                        

                                        tempChar[j] = '\0';
                                        temp = strToNumber(tempChar); //converting to number in order to valuate the bytes//
                                
                                printf("%c", str[i]);
                                i++;

                                if (isspace(str[i]))
                                
                                        while (isspace(str[i]))
                                                i++;
                                
                        
                        fprintf(f," requires %d bytes \n", temp*(sizeof(temp)));
                


                if (str[i] == '*') //for pointers//
                
                        while (str[i] != ',' && str[i] != ';')
                        
                                printf("%c", str[i]);
                                i++;
                                if (str[i]==' ')
                                
                                        while (str[i]==' ')
                                                i++;
                                
                        
                        fprintf(f," requires %d bytes \n", 4);
                
                if (str[i] != ';')
                        i++;
        

 fclose(f);


int theSizeOf(char* str) // checking the size of the variable

        if (strcmp(str, "int")==0 || strcmp(str, "long")==0 || strcmp(str, "float")==0)
                return 4;
        else if (strcmp(str, "char")==0)
                return 1;
        else if (strcmp(str, "double")==0)
                return 8;
        else if (strcmp(str, "short")==0)
                return 2;
        else 
            return 0;



int strToNumber(char* str) //converting the string to number//

        int temp=1;
        int num=0;
        int t;
        int i;
        int length = strlen(str);
        for (i = length-1; i >= 0; i--)
        
                t = str[i] - '0';
                num += t * temp;
                temp *= 10;
        
        return num;
 

谢谢大家的帮助!

【讨论】:

printf("%c", str[i]); --> fprintf(f, "%c", str[i]);, fprintf(f," requires %d bytes \n", temp*(sizeof(temp))); --> fprintf(f," requires %d bytes \n", temp*size);【参考方案4】:

使用 sscanf 的示例。

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

#define BUFF_SIZE 128

void bytesPerValue(FILE *ofp, char str[]);

int main(int argc, char *argv[])
    char str[BUFF_SIZE];
    char *inp_filename, *out_filename;
    FILE *ifp, *ofp;

    if(argc != 3)
        fprintf(stderr, "Usage: %s input_filename output_filename\n", argv[0]);
        return EXIT_FAILURE;
    

    inp_filename = argv[1], out_filename = argv[2];
    if(NULL==(ifp = fopen(inp_filename, "r")))
        fprintf(stderr, "Couldn't open file : %s\n", inp_filename);
        return EXIT_FAILURE;
    
    if(NULL==(ofp = fopen(out_filename, "w")))
        fprintf(stderr, "Couldn't open file : %s\n", out_filename);
        return EXIT_FAILURE;
    

    while(fgets(str, sizeof str, ifp))
        //str[strcspn(str, "\n")] = 0;//chomp newline
        bytesPerValue(ofp, str);
    
    fclose(ifp), fclose(ofp);


struct size_of_type 
    const char *name;
    int size;
 Type_size[] = 
     "char"  , sizeof(char) ,
     "double", sizeof(double) ,
     "float" , sizeof(float) ,
     "int"   , sizeof(int) ,
     "long"  , sizeof(long) ,
     "short" , sizeof(short) ,
;

int cmp(const void *a, const void *b)
    return strcmp(*(char **)a, *(char **)b);


int theSizeOf(const char *type)
    struct size_of_type *stp;
    if(!*type)//""
        return 0;
    stp = bsearch(&type, Type_size, sizeof(Type_size)/sizeof(*Type_size), sizeof(*Type_size), cmp);
    return stp ? stp->size : -1;


enum  UNKNOWN = -1, NONE ;
#define UNDER_BAR "_"
#define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
#define ID_CHARS  UPPERCASE LOWERCASE UNDER_BAR

void bytesPerValue(FILE *fp, char str[]) 
    char type[16] = "", rest[BUFF_SIZE];
    char field[BUFF_SIZE], id[BUFF_SIZE], dummy[BUFF_SIZE];
    char *sp, sep=0, end_b, dispname[BUFF_SIZE];
    int typeSize, size, subscript, len;

    sscanf(str, "%s %[^\n]", type, rest);
    typeSize = theSizeOf(type);
    if(typeSize == UNKNOWN)
        fprintf(fp, "%s is unknown type in '%s'\n", type, str);
        return;
     else if(typeSize == NONE)//blank line
        return;
    
    sp = rest;
    for(sp = rest; 2 == sscanf(sp, " %[^,;]%c%n", field, &sep, &len) && (sep == ',' || sep == ';'); sp += len)
        if(3 == sscanf(field, " * %[" ID_CHARS "] [%d %c %s", id, &subscript, &end_b, dummy) && subscript > 0 && end_b == ']')//array of pointer
            typeSize = sizeof(void *);
            size = typeSize * subscript;
            sprintf(dispname, "*%s[]", id);
        
        else if(3 == sscanf(field, " %[" ID_CHARS "] [%d %c %s", id, &subscript, &end_b, dummy) && subscript > 0 && end_b == ']')//array
            size = typeSize * subscript;
            sprintf(dispname, "%s[]", id);
        
        else if(1 == sscanf(field, " * %[" ID_CHARS "] %s", id, dummy))//pointer
            size = typeSize = sizeof(void *);
            sprintf(dispname, "*%s", id);
        
        else if(1 == sscanf(field, " %[" ID_CHARS "] %s", id, dummy))//normal variable
            size = typeSize;
            strcpy(dispname, id);
         else 
            fprintf(fp, "'%s' is invalid format.\n", field);
            continue;
        
        fprintf(fp, "%s requires %d bytes \n", dispname, size);
    
    if(sep != ';')
        fprintf(fp, "'%s' is invalid format.\n", str);
    

【讨论】:

以上是关于读取简单数据声明并以分配给该变量的内存量响应的程序的主要内容,如果未能解决你的问题,请参考以下文章

1如何声明一个类?如何创建类的对象?

C++中内存分配问题

c++中函数中变量内存分配以及返回指针引用类型的思考

malloc 和全局变量声明在 C 中将它们的变量分配到哪里? [复制]

c语言是在声明变量的同时,分配内存的吗?程序结束运行了,内存会释放吗?

Go语言中初始化变量中字面量&Type{}newmake的区别