无法从字符串数组中正确读取

时间:2018-01-04 04:48:36

标签: c

所以对于这个程序我得到一个bnary文件作为输入,我有: 1)读取唯一二进制密钥 2)读完所说的二进制唯一键后,我必须读取前面的字符(例如:查找二进制键 - >打印字符(仅大写和小写)并打印整数。

然而,这不符合预期。我要离开目前为止所得到的东西。任何帮助将不胜感激

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

void splittingFunction(FILE *filePtr, long fileLength)
{
    long binaryInteger, aux;
    char *auxPtr;
    int i=0, n,count=0, beginFlag, endFlag, j;
    long arrSize=0;
    char *buffer=(char*)malloc(fileLength+1);
    if(!buffer)
        printf("Out of Memory");
    n=fread(buffer, fileLength, 1, filePtr);
    buffer[fileLength+1]='\0';
    //for(i=0; i<=fileLength; i++)
    //  printf("%c",buffer[i]);

    arrSize=fileLength/8;

    printf("\nARRAYSIZE=%d", arrSize);
    char **arr=(char**)malloc(arrSize*sizeof(char*));
    for(i=0;i<arrSize;i++)
    {
        arr[i]=(char *)malloc(9*sizeof(char));
    }



    for(i=0;i<arrSize;i++)
    {
       strncpy(arr[i], &buffer[i*8], 8);
       arr[i][8]='\0';

    }
    /*for(i=0;i<arrSize;i++)
    {
        puts(arr[i]);
    }*/

    for(i=0;i<arrSize;i++)
    {
        binaryInteger=strtol(arr[i],&auxPtr,10);
        if(binaryInteger==10001||binaryInteger==11001||binaryInteger==11101||binaryInteger==11111||binaryInteger==10111||binaryInteger==10011)
        {
            i++;
           while(checkType(arr[i])!=0||checkType(arr[i])!=1||checkType(arr[i])!=2)
            {
                aux=strtol(arr[i],&auxPtr,10);
                printf("%c", convertBinaryToDecimal(aux));
            }
        }
    }

    printf("\nCOUNT=%d",count);

    free(buffer);
    free(arr);
}

checkType功能

int checkType(char *str)
{
    long binaryInteger;
    int decimal;
    char *ptr;

    binaryInteger=strtol(str, &ptr, 10);

    decimal=convertBinaryToDecimal(binaryInteger);

    if(decimal>=65 && decimal<=90)
    {
        return 1; //upper case
    }
    else
    if(decimal>=48&&decimal<=57)
    {
        return 0; //integer
    }
    if(decimal>=97&&decimal<=122)
    {
        return 2; //lowercase
    }
    else
        return 0;
}

convertBinaryToDecimal功能

int convertBinaryToDecimal(long n)
{
    int decimalNumber=0,i=0, remainder=0;
    while(n!=0)
    {
        remainder=n%10;
        n/=10;
        decimalNumber+=remainder*pow(2,i);
        ++i;
    }
    return decimalNumber;
}

1 个答案:

答案 0 :(得分:0)

如果没有您的数据文件,就无法确定您的逻辑是什么,但即使没有它,我们也可以提供一些帮助。如评论中所述,您正试图通过buffer nul-terminate 1超出范围。 buffer的索引将0 -> filelength - 1buffer[filelength] = 0;

正确终止

接下来,不要在代码中使用幻数,如果需要常量,请定义它们,例如

#define ARRSZ   8 /* if you need a constant, define one */
#define BASE   10

请勿使用字符所在的数字。它使您的代码更难以阅读,例如。

if(decimal>=65 && decimal<=90)

相反,请使用'A''Z'并稍微打开代码的间距,以使其更具可读性(特别是对于年长的眼睛),例如。

if (decimal >= 'A' && decimal <= 'Z')

以下代码中的注释概述了splittingFunction中的其余错误,缺乏验证(或仅需要清理)。以while ( checkType (arr[i]) != 0 || ...开头的逻辑的最后一点是没有意义的,并且标点字符和符号将失败,因为else中的默认checkType会返回0,就像'0' - '9'一样1}} - 也许elsereturn 3?以下是splittingFunction

的注意事项
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>  /* for strtol conversion validation */

#define ARRSZ   8   /* if you need a constant, define one */
#define BASE   10

void splittingFunction (FILE *filePtr, long fileLength)
{
    int count = 0, i, j;  /* j unused, but suspect intended for while logic */
    long binaryInteger, aux, 
        arrSize = (fileLength + 7) / ARRSZ; 
    char **arr = malloc (arrSize * sizeof *arr), 
        *auxPtr = NULL,
        *buffer = malloc (fileLength + 1);

    if (!buffer) {  /* validate buffer memory allocation */
        perror ("malloc error - buffer");
        exit (EXIT_FAILURE);
    }

    /* validate read of fileLength bytes */
    if (fread(buffer, 1, fileLength, filePtr) != fileLength) {
        perror ("fread failed.");
        exit (EXIT_FAILURE);
    }
    buffer[fileLength] = 0; /* nul-terminate - questionable... */

    printf("\nARRAYSIZE = %d\n", arrSize);

    if (!arr) {  /* validate arr pointer allocation */
        perror ("malloc error - arr ptrs");
        exit (EXIT_FAILURE);
    }

    for (i = 0; i < arrSize; i++) {     /* for each in arrSize */
        arr[i] = malloc (ARRSZ + 1);    /* allocate ARRSZ + 1 bytes */
        if (!arr[i]) {                  /* validate arr[i] storage */
            perror ("malloc error - arr[i]");
            exit (EXIT_FAILURE);
        }
        memcpy (arr[i], &buffer[i * ARRSZ], ARRSZ); /* copy ARRSZ bytes */
        arr[i][ARRSZ] = 0;                          /* nul-terminate */
        puts (arr[i]);                  /* output string (optional) */
    }

    for (i = 0; i < arrSize; i++) {
        errno = 0;                          /* reset errno for validation */
        binaryInteger = strtol (arr[i], &auxPtr, BASE);
        if ((a[i] == auxPtr) || errno) {    /* validate conversion */
            perror ("strtol a[i] converison");
            exit (EXIT_FAILURE);
        }
        if (binaryInteger == 10001 ||       /* check defined values */
            binaryInteger == 11001 || 
            binaryInteger == 11101 ||       /* ALL represent       */
            binaryInteger == 11111 ||       /* NON-printable chars */
            binaryInteger == 10111 ||       /* (decimal 17 - 31)   */
            binaryInteger == 10011 ) {
            // i++;     /* DO NOT INCREMENT FOR LOOP COUNTER WITHIN LOOP */
            count++;    /* ( it looks like you intended count++ ) */
            /*
             * This logic makes no sense !
             * aux will equal binaryInteger (again)
             * there is only one arr[i], 'while' not needed, 'if' ?
             */
            while ( checkType (arr[i]) != 0 ||
                    checkType (arr[i]) != 1 ||
                    checkType (arr[i]) != 2 ) {
                /* ?? this is binaryInteger again ?? */
                // aux = strtol (arr[i], &auxPtr, BASE);
                printf ("%c", convertBinaryToDecimal(aux));
            }
        }
    }

    printf("COUNT = %d\n",count);

    free(buffer);
    for (i = 0; i < arrSize; i++)   /* you must free storage for each arr[i] */
        free (arr[i]);
    free(arr);                      /* then you free arr pointer */
}

注意: C避免使用camelCaseMixedCase变量名称支持所有小写,同时保留用于宏和常量的大写名称)

convertBinaryToDecimal中,无需要求math.h加入pow (2, i)。为什么? pow (2, i)只是i左移,例如而不是decimalNumber+=remainder*pow(2,i);,只需使用decimalNumber += remainder << i;即可。例如:

int convertBinaryToDecimal (long n)
{
    int decimalNumber=0,
        i=0, 
        remainder=0;

    while (n)
    {
        remainder = n % 10;
        n /= 10;
        decimalNumber += remainder << i;
        ++i;
    }
    return decimalNumber;
}

仔细检查,尤其是添加的验证,并让我知道您在splittingFunction的上一部分中的用途,如果您有任何其他问题,我们很乐意为您提供进一步的帮助。