Using fscanf with a while loop to store a char and int
Im am trying to use fscanf to read through a file of hex numbers that either have a char followed by numbers or just numbers and no char. The fscanf appears to work for the first line of the file but that's it.
FILE
E10
20
22
18
E10
210
12
CODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv) {
FILE * iFile;
char instr;
unsigned long long int address;
iFile = fopen("addresses.txt", "r");
if(iFile != NULL){
while (fscanf(iFile, "%c%x", &instr, &address) > 0){
printf("%c", instr); //This just works for the first line
}
}
fclose(iFile);
return 0;
}
c while-loop scanf
add a comment |
Im am trying to use fscanf to read through a file of hex numbers that either have a char followed by numbers or just numbers and no char. The fscanf appears to work for the first line of the file but that's it.
FILE
E10
20
22
18
E10
210
12
CODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv) {
FILE * iFile;
char instr;
unsigned long long int address;
iFile = fopen("addresses.txt", "r");
if(iFile != NULL){
while (fscanf(iFile, "%c%x", &instr, &address) > 0){
printf("%c", instr); //This just works for the first line
}
}
fclose(iFile);
return 0;
}
c while-loop scanf
When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
– paddy
Nov 12 at 1:58
@paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
– Matthew
Nov 12 at 2:04
What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of%x
. If you stepped through your program with a debugger or added extra outputs (such as whatfscanf
returns, or the value inaddress
) you might figure out what's happening on your own.
– paddy
Nov 12 at 2:16
@paddy I figured it out, just had to add a space infront of the first %
– Matthew
Nov 12 at 2:21
You are using the wrong format specifier,%x
is forunsigned int
– M.M
Nov 12 at 3:29
add a comment |
Im am trying to use fscanf to read through a file of hex numbers that either have a char followed by numbers or just numbers and no char. The fscanf appears to work for the first line of the file but that's it.
FILE
E10
20
22
18
E10
210
12
CODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv) {
FILE * iFile;
char instr;
unsigned long long int address;
iFile = fopen("addresses.txt", "r");
if(iFile != NULL){
while (fscanf(iFile, "%c%x", &instr, &address) > 0){
printf("%c", instr); //This just works for the first line
}
}
fclose(iFile);
return 0;
}
c while-loop scanf
Im am trying to use fscanf to read through a file of hex numbers that either have a char followed by numbers or just numbers and no char. The fscanf appears to work for the first line of the file but that's it.
FILE
E10
20
22
18
E10
210
12
CODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char** argv) {
FILE * iFile;
char instr;
unsigned long long int address;
iFile = fopen("addresses.txt", "r");
if(iFile != NULL){
while (fscanf(iFile, "%c%x", &instr, &address) > 0){
printf("%c", instr); //This just works for the first line
}
}
fclose(iFile);
return 0;
}
c while-loop scanf
c while-loop scanf
asked Nov 12 at 1:52
Matthew
25
25
When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
– paddy
Nov 12 at 1:58
@paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
– Matthew
Nov 12 at 2:04
What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of%x
. If you stepped through your program with a debugger or added extra outputs (such as whatfscanf
returns, or the value inaddress
) you might figure out what's happening on your own.
– paddy
Nov 12 at 2:16
@paddy I figured it out, just had to add a space infront of the first %
– Matthew
Nov 12 at 2:21
You are using the wrong format specifier,%x
is forunsigned int
– M.M
Nov 12 at 3:29
add a comment |
When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
– paddy
Nov 12 at 1:58
@paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
– Matthew
Nov 12 at 2:04
What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of%x
. If you stepped through your program with a debugger or added extra outputs (such as whatfscanf
returns, or the value inaddress
) you might figure out what's happening on your own.
– paddy
Nov 12 at 2:16
@paddy I figured it out, just had to add a space infront of the first %
– Matthew
Nov 12 at 2:21
You are using the wrong format specifier,%x
is forunsigned int
– M.M
Nov 12 at 3:29
When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
– paddy
Nov 12 at 1:58
When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
– paddy
Nov 12 at 1:58
@paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
– Matthew
Nov 12 at 2:04
@paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
– Matthew
Nov 12 at 2:04
What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of
%x
. If you stepped through your program with a debugger or added extra outputs (such as what fscanf
returns, or the value in address
) you might figure out what's happening on your own.– paddy
Nov 12 at 2:16
What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of
%x
. If you stepped through your program with a debugger or added extra outputs (such as what fscanf
returns, or the value in address
) you might figure out what's happening on your own.– paddy
Nov 12 at 2:16
@paddy I figured it out, just had to add a space infront of the first %
– Matthew
Nov 12 at 2:21
@paddy I figured it out, just had to add a space infront of the first %
– Matthew
Nov 12 at 2:21
You are using the wrong format specifier,
%x
is for unsigned int
– M.M
Nov 12 at 3:29
You are using the wrong format specifier,
%x
is for unsigned int
– M.M
Nov 12 at 3:29
add a comment |
1 Answer
1
active
oldest
votes
In such cases, where you will be trying to parse the same line many times, it is better to read the line into memory, and then deal with the data in memory, rather than on disk.
char line[MAXLINE];
fgets(line, MAXLINE, iFile);
Then you have what I call the "sscanf ladder," which is a series of if
-else if
clauses, each of which attempts to parse line
in different ways. The condition would examine the return value of sscanf
, since the number of objects successfully read is the return value. So we use this number to distinguish among several different formats:
if (sscanf(line, "%c%x", &instr, &address) == 2)
/* you have an instruction and an address */
else if (sscanf(line, "%x", &address) == 1)
/* you have an address only */
Since, in your case, this is a loop condition, you will have to refactor this into a function of its own:
int readAtLeastAddress(const char *const line, char *instr, unsigned long long *address)
{
return sscanf(line, "%c%x", instr, address) == 2 || sscanf(line, "%x", &address) == 1;
}
Then you would rewrite the loop as such
while (readAtLeastAddress(line, &instr, &address)) {
printf("%c", instr);
}
Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the%c%x
pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something likeisalpha
orisdigit
to test the first character of the line.
– paddy
Nov 12 at 3:05
You use the wrong format specifier ,%x
is forunsigned int
– M.M
Nov 12 at 3:29
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53255077%2fusing-fscanf-with-a-while-loop-to-store-a-char-and-int%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
In such cases, where you will be trying to parse the same line many times, it is better to read the line into memory, and then deal with the data in memory, rather than on disk.
char line[MAXLINE];
fgets(line, MAXLINE, iFile);
Then you have what I call the "sscanf ladder," which is a series of if
-else if
clauses, each of which attempts to parse line
in different ways. The condition would examine the return value of sscanf
, since the number of objects successfully read is the return value. So we use this number to distinguish among several different formats:
if (sscanf(line, "%c%x", &instr, &address) == 2)
/* you have an instruction and an address */
else if (sscanf(line, "%x", &address) == 1)
/* you have an address only */
Since, in your case, this is a loop condition, you will have to refactor this into a function of its own:
int readAtLeastAddress(const char *const line, char *instr, unsigned long long *address)
{
return sscanf(line, "%c%x", instr, address) == 2 || sscanf(line, "%x", &address) == 1;
}
Then you would rewrite the loop as such
while (readAtLeastAddress(line, &instr, &address)) {
printf("%c", instr);
}
Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the%c%x
pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something likeisalpha
orisdigit
to test the first character of the line.
– paddy
Nov 12 at 3:05
You use the wrong format specifier ,%x
is forunsigned int
– M.M
Nov 12 at 3:29
add a comment |
In such cases, where you will be trying to parse the same line many times, it is better to read the line into memory, and then deal with the data in memory, rather than on disk.
char line[MAXLINE];
fgets(line, MAXLINE, iFile);
Then you have what I call the "sscanf ladder," which is a series of if
-else if
clauses, each of which attempts to parse line
in different ways. The condition would examine the return value of sscanf
, since the number of objects successfully read is the return value. So we use this number to distinguish among several different formats:
if (sscanf(line, "%c%x", &instr, &address) == 2)
/* you have an instruction and an address */
else if (sscanf(line, "%x", &address) == 1)
/* you have an address only */
Since, in your case, this is a loop condition, you will have to refactor this into a function of its own:
int readAtLeastAddress(const char *const line, char *instr, unsigned long long *address)
{
return sscanf(line, "%c%x", instr, address) == 2 || sscanf(line, "%x", &address) == 1;
}
Then you would rewrite the loop as such
while (readAtLeastAddress(line, &instr, &address)) {
printf("%c", instr);
}
Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the%c%x
pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something likeisalpha
orisdigit
to test the first character of the line.
– paddy
Nov 12 at 3:05
You use the wrong format specifier ,%x
is forunsigned int
– M.M
Nov 12 at 3:29
add a comment |
In such cases, where you will be trying to parse the same line many times, it is better to read the line into memory, and then deal with the data in memory, rather than on disk.
char line[MAXLINE];
fgets(line, MAXLINE, iFile);
Then you have what I call the "sscanf ladder," which is a series of if
-else if
clauses, each of which attempts to parse line
in different ways. The condition would examine the return value of sscanf
, since the number of objects successfully read is the return value. So we use this number to distinguish among several different formats:
if (sscanf(line, "%c%x", &instr, &address) == 2)
/* you have an instruction and an address */
else if (sscanf(line, "%x", &address) == 1)
/* you have an address only */
Since, in your case, this is a loop condition, you will have to refactor this into a function of its own:
int readAtLeastAddress(const char *const line, char *instr, unsigned long long *address)
{
return sscanf(line, "%c%x", instr, address) == 2 || sscanf(line, "%x", &address) == 1;
}
Then you would rewrite the loop as such
while (readAtLeastAddress(line, &instr, &address)) {
printf("%c", instr);
}
In such cases, where you will be trying to parse the same line many times, it is better to read the line into memory, and then deal with the data in memory, rather than on disk.
char line[MAXLINE];
fgets(line, MAXLINE, iFile);
Then you have what I call the "sscanf ladder," which is a series of if
-else if
clauses, each of which attempts to parse line
in different ways. The condition would examine the return value of sscanf
, since the number of objects successfully read is the return value. So we use this number to distinguish among several different formats:
if (sscanf(line, "%c%x", &instr, &address) == 2)
/* you have an instruction and an address */
else if (sscanf(line, "%x", &address) == 1)
/* you have an address only */
Since, in your case, this is a loop condition, you will have to refactor this into a function of its own:
int readAtLeastAddress(const char *const line, char *instr, unsigned long long *address)
{
return sscanf(line, "%c%x", instr, address) == 2 || sscanf(line, "%x", &address) == 1;
}
Then you would rewrite the loop as such
while (readAtLeastAddress(line, &instr, &address)) {
printf("%c", instr);
}
answered Nov 12 at 2:20
stackptr
8,28023256
8,28023256
Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the%c%x
pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something likeisalpha
orisdigit
to test the first character of the line.
– paddy
Nov 12 at 3:05
You use the wrong format specifier ,%x
is forunsigned int
– M.M
Nov 12 at 3:29
add a comment |
Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the%c%x
pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something likeisalpha
orisdigit
to test the first character of the line.
– paddy
Nov 12 at 3:05
You use the wrong format specifier ,%x
is forunsigned int
– M.M
Nov 12 at 3:29
Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the
%c%x
pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something like isalpha
or isdigit
to test the first character of the line.– paddy
Nov 12 at 3:05
Partly good advice, but not practical since any input containing at least two characters where the second character is a number will match the
%c%x
pattern. Reading by line of course is the right way to begin, but the logic for interpreting the line in this case should be using something like isalpha
or isdigit
to test the first character of the line.– paddy
Nov 12 at 3:05
You use the wrong format specifier ,
%x
is for unsigned int
– M.M
Nov 12 at 3:29
You use the wrong format specifier ,
%x
is for unsigned int
– M.M
Nov 12 at 3:29
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53255077%2fusing-fscanf-with-a-while-loop-to-store-a-char-and-int%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
When you say it "works" for the first line, you then imply it "doesn't work" for successive lines. Please define what you mean by that. What behavior are you seeing? What behavior do you expect?
– paddy
Nov 12 at 1:58
@paddy so the first line of the file is E10 so instr should print out E, which it does. But when it gets to the 5th line of the file which again is E10, that E is not showing up.
– Matthew
Nov 12 at 2:04
What does it display for the 2nd, 3rd and 4th lines? My guess would be it writes the newline left in the stream from the previous read of
%x
. If you stepped through your program with a debugger or added extra outputs (such as whatfscanf
returns, or the value inaddress
) you might figure out what's happening on your own.– paddy
Nov 12 at 2:16
@paddy I figured it out, just had to add a space infront of the first %
– Matthew
Nov 12 at 2:21
You are using the wrong format specifier,
%x
is forunsigned int
– M.M
Nov 12 at 3:29