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