Formatting a .csv file to print a table (C) [closed] - c

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
I have to print formatted table of csv file. I wonder if you know about any specific library or a tool that can help me with this - I just didn't find anything by googling.
this is the code and the code works fine, just have to print it like a formatted table. thanks!
void opportunity_table()
{
int i = 3;
char line[LINESIZE];
FILE* fp = fopen("opportunity_table.csv", "r");
if (!fp) {
printf("File failed to open!\n");
exit(1);
}
while (fgets(line, LINESIZE, fp)) {
while (line[i] != '\n') {
if (line[i] == ',') {
printf("%s ", "");
}
else
printf("%c", line[i]);
i++;
}
i = 0;
puts(" ");
}
}
the input I get from running this code is messy and look really bad.

Make use of the width and precision fields of the %s specifier. The width field sets a width of at least the specified characters. The precision field will print up to the specified number of characters. Works as long as width is greater than precision.
strpbrk will give a pointer to the next character in the string or NULL.
The format string "%*.*s" will right justify the printing. Use "%-*.*s" to left justify.
#include <stdio.h>
#include <string.h>
#define WIDTH 7
int main( void) {
char csv[] = "a,b,cde,fghij,i,jh\n";
char *item = csv;
char *comma = NULL;
while ( *item && ( comma = strpbrk ( item, ",\n"))) {//pointer to each comma and the newline
printf ( "%*.*s", WIDTH, comma - item, item);
item = comma + 1;//skip the comma or newline
}
printf ( "\n");
return 0;
}
If the width of the fields needs to vary, an array of widths could be used.
#include <stdio.h>
#include <string.h>
int main( void) {
char csv[4][50] = {
"a,b,cde,fghij,i,jh\n",
"i,jk,lmno,pq,rst,uvw\n",
"0,1,2,3456,78,9\n",
"x,y,z,01,2345,6789\n"
};
char *item = NULL;
char *comma = NULL;
int width[] = { 3, 4, 6, 7, 6, 5};
int field = 0;
for ( int loop = 0; loop < 4; ++loop) {
field = 0;
item = csv[loop];
while ( *item && ( comma = strpbrk ( item, ",\n"))) {//pointer to each comma and the newline
printf ( "%*.*s", width[field], comma - item, item);
item = comma + 1;//skip the comma or newline
field++;
}
printf ( "\n");
}
return 0;
}
This could be customized by reading the file twice. The number of fields and the maximum width could be determined in the first read. Read the file the second time and print using the calculated widths.

Related

Extract a multi-digit decimal from a string in c [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I have a buffer containing a null terminated string buf[100].
I am using fgets to read from a fd into the buffer in a while loop.
Here is an example string that might be read into the buffer
Sundaresan Sulochana 579 917 8024
All strings follow this convention of "last first area_code ...". I want to extract the area code as a decimal (so in this case 579). I am currently iterating through the string looking for spaces, finding the start of the area code, reading 3 characters, then converting to decimal, but I was wondering if there is a more efficient way. I tried sscanf but was getting unexpected results.
Thanks!
input_data = fdopen(in_p[0], "r");
int i, j;
while (fgets(buf, 100, input_data) != NULL) {
if (sscanf(buf, "%*s%*s%d", &new_code) == 1){
printf("code = %d\n", new_code);
}
else
{
printf("Error scanning area code\n");
}
/*
for (i=0,j=0;buf[i] != '\n'; i++){
if (buf[i] == ' '){
j++;
}
if (j == 4){
for(j=0; j<3; j++){
str_code[j] = buf[j+i+1];
}
str_code[3] = '\n';
new_code = atoi(str_code);
break;
}
}*/
User input is best done using a combination of fgets() and strtok(), IMHO. For example, if you with to read a record exactly as you described:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
printf( "last first area_code ... ? " );
fflush( stdout );
char s[1000] = {0};
fgets( s, sizeof(s), stdin );
const char * delimiters = " \t";
char * last_name = strtok( s, delimiters );
char * first_name = strtok( NULL, delimiters );
char * area_code_s = strtok( NULL, delimiters );
int area_code = area_code_s ? atoi( area_code_s ) : 0;
//...
// (Make sure to check that nothing is NULL before trying to print it.
// You should be able to do this when using a code snippet online.)
printf( "%s %s's area code is %d.\n", first_name, last_name, area_code );
}
If you are reading records, it is worth your time to make a struct:
struct person
{
char last_name[50];
char first_name[50];
int area_code;
...
};
And a function to convert a string to a struct:
bool s_to_person( char * s, struct person * p )
{
if (!s) return false;
// ...
// use strtok(), etc here. Make sure to watch out for errors, and
// return true only if nothing went wrong.
return true;
}
Which you can then use in a loop. For example, to fill an array of people:
enum { MAX_PEOPLE = 1000 };
struct person people[MAX_PEOPLE];
int npeople = 0;
char s[1000];
while ((npeople < MAX_PEOPLE)
and s_to_person( fgets( s, sizeof(s), stdin ), people+npeople ))
{
npeople += 1;
}
Make sure to keep your reference handy and avoid passing NULL values as argument to standard functions taking strings.

Read row in a file and print out portion of string [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
Hi I have a text file from whitch i read row by row and paste result into a new file only a portion of string contained between character ! and character $
example:
origin:
Beautifull!day today$
!hello world$is nice
final:
day today
hello world
I have used in past this code and it was working now the output is an empty file.
#include <stdio.h>
#include <alloc.h>
#include <string.h>
FILE *string;
FILE *stringtxt;
int line = 0;
int i = 0;
int j;
char search = 33;
char search2 = 36;
int main(void)
{
stringtxt = fopen("C:\\Users\\Pc\\Desktop\\ups.m3u","a+");
if ((string = fopen("C:\\Users\\Pc\\Desktop\\ups.txt","a+")) == 0)
printf ("ERRORE");
else{
char input[512];
while (fgets(input,512,string)){
line++;
i = strlen(input);
for(j=0;j<i;j++){
if(input[j]==search){
input[j-0] = 0;
}
}
for(j=0;j<i;j++){
if(input[j]==search2){
memmove(input,input + j + 1, strlen(input));
printf("%s\n",input);
fprintf(stringtxt,"%s\n",input);
}
}
}
}
fclose(stringtxt);
}
You have various little errors in your code which prevent your program to do what you want.
As you read from one file and write to the other from the beginning you should use "r" mode to read and "w" mode to write. That would fix the problem that "a" sets the file pointer at the end of file and only allow it to grow.
Then if you want to extract the part starting at search and ending at search2 you should swap the variables.
With those minimal fixes it will become:
...
stringtxt = fopen("C:\\Users\\Pc\\Desktop\\ups.m3u","w"); // change 1
if ((string = fopen("C:\\Users\\Pc\\Desktop\\ups.txt","r")) == 0) //change 2
printf ("ERRORE");
else{
char input[512];
while (fgets(input,512,string)){
line++;
i = strlen(input);
for(j=0;j<i;j++){
if(input[j]==search2){ // change 3
input[j-0] = 0;
}
}
for(j=0;j<i;j++){
if(input[j]==search){ // change 4
memmove(input,input + j + 1, strlen(input));
printf("%s\n",input);
fprintf(stringtxt,"%s\n",input);
}
...
Above code also cleaned indentation and produces the expected result.
From your response to my comment, it seems like you would be satisfied with:
#include <stdio.h>
int
main(void)
{
int c;
int p = 0;
while( ( c = getchar()) != EOF ) {
switch(c){
case '\n': putchar(c); /* fallthru */
case '$': p=0;
}
if( p ){
putchar(c);
}
if( c == '!' ){
p = 1;
}
}
}
With problems like this, it is often not necessary to actually read full lines, and it is much simpler if you do not. This solution will print the data between the first ! and the first $. If you want to match on the inner pair, or the outer pair, it becomes necessary to read more than one character.

C - C file won't count correctly, it is 1 short [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm brand new to C and struggling with some syntax. My goal is to read through a text document in my directory and return a count it's length.
#include <stdio.h>
#include <stdio.h>
#include <ctype.h>
int counter (FILE* inPtr) { //Pointer to the file its reading from
char ln[len]; \\length of file
int counter = 0; \\initializing file
while(fgets(ln,len,inPtr) != NULL{
char* r;
for (r = ln; *r != '0';) {
while (isspace(*run)) {
r++;
}
if(*r == '\0') {
break;
}
else {
counter++;
}
r++;
}
return(counter);
}
}
Basically, I'm just trying to go past the spaces between words, break when we go over the length (when it runs to null), and count as we go. And then it keeps running until it points to no a space or null. I think I have the right idea by syntax is off...any advice?
There are many syntax issues in your code:
you include <stdio.h> twice
single line comments are started with //, not \\
the null pointer is defined as NULL, not null
there is a missing ) in while(fgets(ln,len,inPtr) != null {
there is a spurious ; in if(*r == '\0'); {
you probably mean to test *r != '\0' instead of *r != '0' if the for loop.
you should move the return counter; outside the body of the while loop.
Here is a modified, reformated and simplified version:
#include <stdio.h>
#include <ctype.h>
int counter(FILE *inPtr) { // Pointer to the file its reading from
char ln[256]; // line buffer
int counter = 0; // number of non white space characters in file
while (fgets(ln, sizeof(ln), inPtr) != NULL) {
for (char *r = ln; *r != '\0'; r++) {
if (!isspace((unsigned char)*r)) {
counter++;
}
}
}
return counter;
}
Here is an even simpler version reading one byte at a time:
#include <stdio.h>
#include <ctype.h>
// return number of non white space characters in file from current position
int counter(FILE *inPtr) { // Pointer to the file its reading from
int c, counter = 0;
while ((c = getc(inPtr)) != EOF) {
counter += !isspace(c);
}
return counter;
}
If your purpose is to count words instead of bytes, you should modify it to skip whitespace, test if at end of line, increment the word count and skip all non whitespace bytes inside the while loop body:
// return the number of space separated words in the file
int counter(FILE *inPtr) { // Pointer to the file its reading from
char ln[256]; // line buffer
int counter = 0; // number of space separated words in the file
while (fgets(ln, sizeof(ln), inPtr) != NULL) {
for (char *r = ln;;) {
// skip white space before the word
while (isspace((unsigned char)*r) {
r++;
}
if (*r == '\0') // end of the line
break;
counter++; // count the word
// skip the word
while (*r != '\0' && !isspace((unsigned char)*r) {
r++;
}
}
}
return counter;
}

csv file visualization program [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I would like to write a program that will open a csv file and create its visualization in a txt file.
I mean:
input:
(this is csv file)
apple;orange;strawberry
car;warsaw;ansi
output in txt file
apple|orange|strawberry
car |warsaw| ansi
The idea is that the width of the whole column should be adjusted to the longest expression in it
output in my program
apple|orange|strawberry
|car|warsaw|ansi
|
I have too many separators, and they're not in line
My code:
#include <stdio.h>
#include <string.h>
#include <string.h>
#define MAXLINE 1000
int how_many_delimiter(char array[]);
int main(void)
{
FILE *f,*f_2;
int *size_of_column, counter, hmd, min;
char corrector[] = ";", rows[MAXLINE], *clipboard;
f = fopen("ex-5.csv", "r");
f_2 = fopen("wynik.txt", "w");
fgets(rows, MAXLINE, f);
hmd = how_many_delimiter(rows);
size_of_column = (int*)calloc(hmd,sizeof(int));
min=10;
while(fgets(rows, MAXLINE, f))
{
clipboard = strtok(rows, corrector);
counter=0;
if(strlen(clipboard)>size_of_column[counter])
{
size_of_column[counter] = strlen(clipboard);
}
while(clipboard!=NULL)
{
if(strlen(clipboard)>size_of_column[counter])
{
size_of_column[counter] = strlen(clipboard);
}
clipboard = strtok(NULL,corrector);
counter++;
}
}
fclose(f);
f = fopen("ex-5.csv", "r");
while(fgets(rows, MAXLINE, f))
{
clipboard = strtok(rows, corrector);
counter=0;
while(clipboard!=NULL)
{
fprintf(f_2,"%-*s|",size_of_column[counter], clipboard);
clipboard = strtok(NULL,corrector);
counter++;
}
}
fclose(f);
fclose(f_2);
return 0;
}
int how_many_delimiter(char array[])
{
int counter, i;
i = 0;
counter = 1;
while(array[i]!='\n'&& array[i]!=EOF)
{
if(array[i]==';') counter++;
i++;
}
return counter;
}
Steps to do this (using an alternate to the "%*s", width method):
Loop to get length of longest word in all categories
int len = strlen(longestWord);
Create format string container char formatStr[80];
Populate formatStr: sprintf(formatStr, "%s%d%s", "%", len+5, "s");
+5 is arbitrary, change as needed for space between columns.
Use formatStr in the printf() statements for each word.
So for example the longest word shown in your example is strawberry. My suggestion was to programmatically parse all of the words into buffers, and loop on them, performing strlen() on each to determine longest. Once you've found, in this case, strawberry, len will be 10, so the format specifier would be "%15s" (if you use my recommended +5). But the value 15 will be in an int variable by then (say for example int longest. Since inserting it directly into the normal format string: ( "%longests" ) will not compile, it will need to be packaged up into a format string, formatStr as shown in bullets above, and here:
sprintf(formatStr, "%s%d%s", "%", longest + 5, "s|");
( Will look like: "%s15s|" )
Once this is done, you can use the format string in the printf statements
This then:
fprintf(f_2,"%-*s|",size_of_column[counter], clipboard);
Becomes:
fprintf(f_2,formatStr, clipboard);
(either method will work.)

Parsing a line from file [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a file with the following line:
numOfItems = 100
I want to read the line from file and initialize the attribute "numOfItems" to 100. How could I do it, i.e, deleting the unnecessary spaces and read only the values I need?
Also, I have another line which is:
num Of Items = 100
which I need to parse as error (attributes and values cannot contain spaces).
In the first case I know how to remove the spaces at the beginning, but not the intervening spaces. In second case I don't know what to do.
I thought to use strtok, but couldn't manage to get what I needed.
Please help, thanks!
Using fgets and sscanf with %s %d and %n should parse lines of the format "item = value"
#include <stdio.h>
#include <string.h>
int main( void){
char line[256] = { '\0'};
char item[50] = { '\0'};
int value = 0;
int used = 0;
printf ( "enter string as \"item = value\" or x to exit\n");
while ( ( fgets ( line, 256, stdin))) {
if ( strcmp ( line, "x\n") == 0) {
break;
}
//%49s to prevent too many characters in item[50]
//%n will report the number of characters processed by the scan
//line[used] == '\n' will succeed if the integer is followed by a newline
if ( ( ( sscanf ( line, "%49s = %d%n", item, &value, &used)) == 2) && line[used] == '\n') {
printf ( "parsed item \"%s\" value \"%d\"\n", item, value);
}
else {
printf ( "problem parsing \n\t%s\n", line);
}
printf ( "enter string as \"item = value\" or x to exit\n");
}
return 0;
}

Resources