Home > Software design >  Why am I getting extra character when trying to write to file?
Why am I getting extra character when trying to write to file?

Time:10-14

This is supposed to flips upper and lower case letters but its not flipping just adding random characters.


    int  in = open(argv[1], O_RDONLY);
    int out = open(argv[2], O_CREAT | O_WRONLY, 0624);
    char buff[65];
      buff[64] = '\0';
  
    if(argc < 2){
        printf("Not enough arguments");
        return 1;
    }
    else if(argv[1] == 0 || argv[2] == 0){
        printf("No file");
        return 1;
    }
int i = read(in,buff,64);
        
for (i = 0; buff[i]!='\0'; i  ) {
    if(buff[i] >= 'a' && buff[i] <= 'z') {
      printf("%d", buff[i]-32);
    } else if (buff[i] >= 'A' && buff[i] <= 'Z') {
        printf("%d", buff[i] 32);    
    } else {
       printf("%d", buff[i]);
      }
    }
    
    write(out, buff, 64);
    close(in);
    close(out);
    return 0;
}

How do I get it to read the character and flip without extras?

CodePudding user response:

If your input file does not contain a '\0' as last character, your condition buff[i]!='\0' depends on random contents.

Change these lines:

char buff[65];
      buff[64] = '\0';

to this line:

char buff[65] = { 0 };

However, read() tells you the number of bytes it read. You can use that value to mark the end:

int n = read(in,buff,64);
        
for (i = 0; i < n; i  ) {
    /* ... */
}

write(out, buff, n);

CodePudding user response:

Write a function that reads a line, up to some maximum size; separate the logic of reading the file from other processing,

int readline(int fh, char* buff, int maxsize) {
    int rc = read(fh,buff,maxsize);
    if( rc < 0 ) {
        printf("read error, %d\n",rc);
        return rc;
    }
    return rc;
}

Write a function that writes the converted buffer, separate the logic of writing the file and other processing,

int writeline(int fh, char* buff, int len) {
    int wc = write(fh, buff, len);
    return wc;  
}

Write a function that flips the case; separate the logic from reading and writing the file,

char* flipcase(char* buff, int len) {
    if(!buff || len<1) return buff;
    char* cp = buff;
    for (int ix = 0; ix<len; ix  , cp   ) {
        if( isupper(*cp) { // in [A-Z]
            // printf("%d", *cp-32); // not portable
            *cp = tolower(*cp); // modify buff[ix]
        }
        else if( islower(*cp) ) { // in [a-z]
            // printf("%d", *cp 32); // not portable
            *cp = toupper(*cp); // modify buff[ix]
        }
        // else {
        //     unchanged
        // }
        // printf("%d", *cp);
    }
    return buff;
}

Build a function that handles each line separately,

# define MAXLINE (256) // named 'constant'

int doline(int fin, int fout) {
    char buff[MAXLINE 1] = { 0 };
    int rc = readline(fin, buff, MAXLINE);
    // check results of readline here
    flipcase(buff, rc);
    int wc = writeline(fout, buff, rc);
    // check results of writeline here
    return rc;
}

Here you would handle your (argc, argv) and open your files,

if(argc < 3) {
    printf("Not enough arguments");
    return 1;
}
if(argv[1] == 0 || argv[2] == 0) {
    printf("No file");
    return 1;
}
int  fin = open(argv[1], O_RDONLY);
if( !fin ) {
    printf("open %s failed\n",argv[1]);
    return 2;
}
int fout = open(argv[2], O_CREAT | O_WRONLY, 0624);
if( !fout ) {
    printf("open %s failed\n",argv[2]);
    close(fout);
    return 2;
}

int rc = 0;
// process one line
rc = doline(fin,fout);
// or, process every line in file
for( ; rc = doline(fin,fout) >= 0; ) {
}

close(fin);
close(fh);
  • Related