Home > Enterprise >  Try to Separate String in C read from a txt
Try to Separate String in C read from a txt

Time:08-14

Make the following code to be able to separate the string:

CristinaRodriguezRiveraComputacion210302414

but I want to know how much of the code I have to modify or what I can modify of the code so that I can separate this:

CristinaRodriguezRiveraComputacion210302414RamiroSilvaPerezIndustrial217890453PatriciaDuranSanchezCivil215643525RaulColinGranadosComputacion215678342

the code correctly separates the first string but I would like to implement the pertinent modifications :)

#include <stdio.h> 
#include <errno.h> 
#include <ctype.h> 
#include <string.h> 
 
 
int complete_lowercase(char dinamic[], int longdinamico, char destiny[], int ini) { 
   int fin = ini   1; 
   while (islower(dinamic[fin])) { 
        fin; 
   } 
   memcpy(destiny, &dinamic[ini], fin - ini); 
   return fin; 
} 
 
void separate_data(char dinamic[], int longdinamic, char name[], char father[], char mother[], char degree[], char id[]) { 
   int ini_father = complete_lowercase(dinamic, longdinamic, name, 0); 
   int ini_mother = complete_lowercase(dinamic, longdinamic, father, ini_father); 
   int ini_degree = complete_lowercase(dinamic, longdinamic, mother, ini_mother); 
   int ini_id = complete_lowercase(dinamic, longdinamic, degree, ini_degree); 
   memcpy(id, &dinamic[ini_id], longdinamic - ini_id); 
} 
 
int main(){ 
    FILE*  ent = fopen("DatosEntrada.txt","r"); 
    FILE*  sal = fopen("SalidaBytes.txt","a"); 
 
    if(ent != NULL){ 
        char name[15]; 
        char father[15]; 
        char mother[15]; 
        char degree[15]; 
        char id[15]; 
 
        memset(name, ' ', sizeof(name)); 
        memset(father, ' ', sizeof(father)); 
        memset(mother, ' ', sizeof(mother)); 
        memset(degree, ' ', sizeof(degree)); 
        memset(id, ' ', sizeof(id)); 
 
        fseek(ent, 0, SEEK_END); //file length 
        int longarch = ftell(ent); 
        rewind(ent);  //go back to the start 
 
        char dinamic[longarch 1]; 
        fscanf(ent,"%s",&dinamic); 
 
        separate_data(dinamic, longarch 1, name, father, mother, degree, id); 
 
        fwrite(name, sizeof(char), 15, sal); 
        fwrite(father, sizeof(char), 15, sal); 
        fwrite(mother, sizeof(char), 15, sal); 
        fwrite(degree, sizeof(char), 15, sal); 
        fwrite(id, sizeof(char), 15, sal); 
 
        printf("\nCreated File\n"); 
        fclose(ent); 
        fclose(sal); 
 
    }else{ 
 
       fprintf(stdout, "ERROR: %s", strerror(errno)); 
    } 
 
}

CodePudding user response:

If the current character is a number then search for the next upper case letter, otherwise search for either a number or upper case. This is transition between the current and next word.

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

#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define NUMBER "0123456789"

int main() {
    const char *s = "CristinaRodriguezRiveraComputacion210302414RamiroSilvaPerezIndustrial217890453PatriciaDuranSanchezCivil215643525RaulColinGranadosComputacion215678342";
    for(;;) {
        const char *pattern = strchr(NUMBER, *s) ? UPPER : UPPER NUMBER;
        const char *s2 = strpbrk(s   1, pattern);
        if(!s2) {
            printf("%s\n", s);
            break;
        }
        printf("%.*s\n", s2 - s, s);
        s = s2;
    }
    return 0;
}

and it would generate the following output:

Cristina
Rodriguez
Rivera
Computacion
210302414
Ramiro
Silva
Perez
Industrial
217890453
Patricia
Duran
Sanchez
Civil
215643525
Raul
Colin
Granados
Computacion
215678342

CodePudding user response:

A character could be read from the input file and printed to the output file.
Based on upper case and digits, spaces and newlines can be printed to the output file.

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

int main ( void) {
    size_t len = 0;
    size_t fieldcount = 0;
    FILE*  ent = NULL;
    FILE*  sal = NULL;

    if ( NULL == ( ent = fopen ( "DatosEntrada.txt","r"))) {
        perror ( "DatosEntrada.txt");
        return 1;
    }

    if ( NULL == ( sal = fopen ( "SalidaBytes.txt","w"))) {
        fclose ( ent);
        perror ( "SalidaBytes.txt");
        return 2;
    }

    int in = 0;
    while ( EOF != ( in = fgetc ( ent))) {
        if ( isupper ( (unsigned char)in)) {
              fieldcount;
            if ( 1 < fieldcount && 5 > fieldcount) {
                for ( int space = len; space < 15;   space) {
                    fputc ( ' ', sal);
                }
            }
            len = 0;
            if ( 6 == fieldcount) {
                fputc ( '\n', sal);
                fieldcount = 1;
            }
            fputc ( in, sal);
            continue;
        }
        if ( 4 == fieldcount && len && isdigit ( (unsigned char)in)) {
              fieldcount;
            for ( int space = len; space < 15;   space) {
                fputc ( ' ', sal);
            }
            len = 0;
            fputc ( in, sal);
            continue;
        }
        if ( 15 > len) {
            fputc ( in, sal);
        }
          len;
    }

    fclose ( ent);
    fclose ( sal);
    return 0;
}

The output file is:

Cristina        Rodriguez       Rivera          Computacion     210302414
Ramiro          Silva           Perez           Industrial      217890453
Patricia        Duran           Sanchez         Civil           215643525
Raul            Colin           Granados        Computacion     215678342

CodePudding user response:

There are many ways to approach this problem. @AllanWard has a great approach using string.h functions and a couple of constants. Another approach is to use the macros isupper(), islower() and isdigit() provided in ctype.h. There you can trivially just catch each uppercase letter or each digit preceded by a lowercase letter for separating the words.

Example:

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

int main (void) {
  
  const char *s = "CristinaRodriguezRiveraComputacion210302414RamiroSilvaPer"
                  "ezIndustrial217890453PatriciaDuranSanchezCivil21564"
                  "3525RaulColinGranadosComputacion215678342";
                  
  for (const char *p = s; ; p  ) {
    if (!*p || isupper(*p) || (isdigit(*p) && islower(*(p-1)))) {
      if (p > s) {
        putchar ('\n');
      }
      if (!*p) {
        break;
      }
    }
    putchar (*p);
  }
}

(note: a separate pointer p was used to preserve s (in case you needed it later), but if you were doing the separation in a function you can simply walk-down s (the pointer passed as a parameter) without using a separate pointer)

Example Use/Output

$ ./bin/sepupperdigit
Cristina
Rodriguez
Rivera
Computacion
210302414
Ramiro
Silva
Perez
Industrial
217890453
Patricia
Duran
Sanchez
Civil
215643525
Raul
Colin
Granados
Computacion
215678342

Separating Into 15-Character Fields

If you want your output separated into lines of words with a field-width of 15-characters each, then you simply need to rearrange your tests and keep a counter. The counter is used to determine how many spaces to write after each word in the field.

Adding a counter and rearranging your tests you can do:

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

#define FLDWIDTH 15

int main (void) {
  
  const char *s = "CristinaRodriguezRiveraComputacion210302414RamiroSilvaPer"
                  "ezIndustrial217890453PatriciaDuranSanchezCivil21564"
                  "3525RaulColinGranadosComputacion215678342";
  int n = 0;
  
  for (const char *p = s; ; p  , n  ) {
    if (!*p || (isupper(*p) && isdigit(*(p-1)))) {
      putchar ('\n');
      if (!*p) {
        break;
      }
      n = 0;
    }
    else if (isupper(*p) || (isdigit(*p) && islower(*(p-1)))) {
      if (p > s) {
        int spaces = FLDWIDTH - n;
        while (spaces--) {
          putchar (' ');
        }
        n = 0;
      }
    }
    putchar (*p);
  }
}

(note: you can simply use fputc() instead of putchar() to write the output to a file)

Example Use/Output

$ ./bin/sepupperdigit2
Cristina       Rodriguez      Rivera         Computacion    210302414
Ramiro         Silva          Perez          Industrial     217890453
Patricia       Duran          Sanchez        Civil          215643525
Raul           Colin          Granados       Computacion    215678342
  •  Tags:  
  • c
  • Related