Sponsored Content
Top Forums Programming Correct way to read data of different formats into same struct Post 302940704 by Corona688 on Wednesday 8th of April 2015 12:09:34 PM
Old 04-08-2015
How scanf/fscanf/sscanf work is it scans a string and stops whenever the input doesn't match what you've specified or it finds whitespace. It's kind of like a regex -- you're creating a string which matches the data you want, with various kinds of wildcards. But it's very different from a regex in that it doesn't stop at the end of the line, it stops wherever it pleases. You can force it with %[charstoaccept] / %[^charstonotaccept], a %s-equivalent I first saw in a config file loader which suddenly had to cope with carriage returns when ported to Windows. (And people wonder why I'm paranoid about those.)

Suppose you're scanning
Code:
abcde 3.14159


c d e

with %s %lf %s. It starts with %s, and accepts 'a', 'b', 'c', 'd', 'e' into the string. Then it sees whitespace and decides the string is over.

The space betweeh %s and %lf tells it "whitespace is acceptable", so it skips past the whitespace.

After that, it gets to %lf, scans '3', '.', '1', '4', '1', '5', '9', and processes that into a float, then hits \n which tells it the number's now over.

The space between %lf and %s tells it whitespace is acceptable. So it skips past all three newlines and starts reading 'c' into a string, and stops immediately because it's hit some whitespace. Since it's completely finished the command string "%s %lf %s", it feels no need to do anything with that whitespace and leaves it there for next time.

...Which means, the next time you scan "%s %lf %s", it will quit immediately because %s sees a white space and stops. The point is, fscanf leaves the file things in an unpredictable place unless things go exactly as planned.

This is why I always read entire lines. sscanf() can't choke and leave stdin in a weird place, because the entire line has already been read. If you want sscanf to read several entire lines, it can do that too.

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

typedef struct abc {
  char a[64], b[64], c[64];
} abc;

int main(void)
{
        char buf[4096];
        abc a;

        while(!feof(stdin)) {
                int bpos=0;

                // Read three lines into the same buffer.
                if(!fgets(buf+bpos, 4096-bpos, stdin)) break;
                bpos = strlen(buf); // could be more efficient but you get the idea
                if(!fgets(buf+bpos, 4096-bpos, stdin)) break;
                bpos = strlen(buf);
                if(!fgets(buf+bpos, 4096-bpos, stdin)) break;

                sscanf(buf, "%[^\r\n] %[^\r\n] %[^\r\n]", a.a, a.b, a.c);

                printf("a: %s\nb: %s\nc: %s\n", a.a, a.b, a.c);
        }
}

Code:
$ printf "a b c\nd e f\ng h i\n" | ./a.out

a: a b c
b: d e f
c: g h i

$


Last edited by Corona688; 04-08-2015 at 01:34 PM..
This User Gave Thanks to Corona688 For This Post:
 

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Read from data file

Hi, I have a data file formatted like this: Ex: Mike 3434 Jack 481 Peter 12 Alan 926 I want to get this data into 2 variables: "Names" and "Numbers" that I can using one "for" loop to get the value as Names and Numbers Like this: for i in 0 1 2 3 do echo $Names echo... (12 Replies)
Discussion started by: fongthai
12 Replies

2. UNIX for Advanced & Expert Users

how to read the data from an excel sheet and use those data as variable in the unix c

I have 3 columns in an excel sheet. c1 c2 c3 EIP_ACCOUNT SMALL_TS_01 select A.* from acc; All the above 3 col shoud be passed a variable in the unix code. 1.How to read an excel file 2.How to pass these data as variable to the unic script (1 Reply)
Discussion started by: Anne Grace
1 Replies

3. Programming

writing binary/struct data to file

I am trying to write binary data to a file. My program below: #include <stdlib.h> #include <stdio.h> struct tinner { int j; int k; }; struct touter { int i; struct tinner *inner; }; int main() { struct touter data; data.i = 10; struct tinner... (4 Replies)
Discussion started by: radiatejava
4 Replies

4. UNIX for Dummies Questions & Answers

How to access a struct within a struct?

Can someone tell me how to do this? Just a thought that entered my mind when learning about structs. First thought was: struct one { struct two; } struct two { three; } one->two->three would this be how you would access "three"? (1 Reply)
Discussion started by: unbelievable21
1 Replies

5. Shell Programming and Scripting

Extracting data from a log file with date formats

Hello, I have a log file for the year, which contains lines starting with the data in the format of YYYY-MM-DD. I need to get all the lines that contain the DD being 04, how would I do this? I tried using grep "*-*04" but it didn't work. Any quick one liners I should know about? Thank you. (2 Replies)
Discussion started by: cpickering
2 Replies

6. HP-UX

struct utsname throwing error : Value too large to be stored in data type

Hi, I am trying to fetch sysname and nodename using struct utsname. I have two HP-UX servers on with 10 characters and other with 13 characters host name. For the first one I am getting truncated 8 characters as output but for the second one i am getting "Value too large to be stored in data type"... (1 Reply)
Discussion started by: shivarajbm
1 Replies

7. Programming

Storing C++-struct in file - problem when adding new item in struct

Hi, I have received an application that stores some properties in a file. The existing struct looks like this: struct TData { UINT uSizeIncludingStrings; // copy of Telnet data struct UINT uSize; // basic properties: TCHAR szHost; //defined in Sshconfig UINT iPortNr; TCHAR... (2 Replies)
Discussion started by: Powerponken
2 Replies

8. Shell Programming and Scripting

Help to get correct data using awk

I have this input.|user1 |10.10.10.10 |23|046|1726 (212) |0 |user2 |10.10.10.11 |23|046|43 (17) |0 |test |10.10.10.12 |23|046|45 (10) |0 |test1 |10.10.10.13 |23|046|89 (32) |0 I need to get the data for a user like thisuser1 1726 user2 43 test 45 test1 89... (11 Replies)
Discussion started by: Jotne
11 Replies

9. Shell Programming and Scripting

Shell script to correct the data

Hi, I have below data in my flat file.I would like to remove the quotes and comma necessary from the data.Below is the details I would like to have in my output. Could anybody help me providing the Unix shell script for this. Input : ABC,ABC,10/15/2012,"47,936,164.567 ","1,036,997.453... (2 Replies)
Discussion started by: sonu_pal
2 Replies

10. Shell Programming and Scripting

In PErl script: need to read the data one file and generate multiple files based on the data

We have the data looks like below in a log file. I want to generat files based on the string between two hash(#) symbol like below Source: #ext1#test1.tale2 drop #ext1#test11.tale21 drop #ext1#test123.tale21 drop #ext2#test1.tale21 drop #ext2#test12.tale21 drop #ext3#test11.tale21 drop... (5 Replies)
Discussion started by: Sanjeev G
5 Replies
All times are GMT -4. The time now is 08:55 PM.
Unix & Linux Forums Content Copyright 1993-2022. All Rights Reserved.
Privacy Policy