I need to read lines of strings in a text file that represent movie showings and format them. I need to use sscanf
to scan the string saved by fgets
. My problem is how do I make sscanf
only read upto x amount of characters while also using [^]
specifier. Movie title lengths have a max length of 44. I know C has %0.*s
but I need to use it in combination with [^]
. I tried doing %0.44[^,]
but to no avail. My code is below. I have commented out what I though would be the solution.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const int MAX_TITLE_CHARS = 44; // Maximum length of movie titles
const int LINE_LIMIT = 100; // Maximum length of each line in the text file
char line[LINE_LIMIT];
char inputFileName[25];
FILE *file;
file = fopen("D:\\movies.csv", "r");
char currentLine[LINE_LIMIT];
char movieTitle[MAX_TITLE_CHARS];
char movieTime[5];
char movieRating[5];
fgets(currentLine, LINE_LIMIT, file);
while(!feof(file)){
// sscanf(currentLine, "%[^,],%0.44[^,],%[^,]", movieTime, movieTitle, movieRating);
sscanf(currentLine, "%[^,],%[^,],%[^,]", movieTime, movieTitle, movieRating);
printf("%-44s |\n", movieTitle);
fgets(currentLine, LINE_LIMIT, file);
}
return 0;
}
This prints out the following
Wonders of the World |
Wonders of the World |
Journey to Space |
Buffalo Bill And The Indians or Sitting Bull's History Lesson |
Buffalo Bill And The Indians or Sitting Bull's History Lesson |
Buffalo Bill And The Indians or Sitting Bull's History Lesson |
Adventure of Lewis and Clark |
Adventure of Lewis and Clark |
Halloween |
I need to it be
Wonders of the World |
Wonders of the World |
Journey to Space |
Buffalo Bill And The Indians or Sitting Bull |
Buffalo Bill And The Indians or Sitting Bull |
Buffalo Bill And The Indians or Sitting Bull |
Adventure of Lewis and Clark |
Adventure of Lewis and Clark |
Halloween |
CodePudding user response:
sscanf(currentLine, "%[^,],C[^,],%[^,]", movieTime, movieTitle, movieRating);
Where 43 is the amount of chars to read and one left for a null terminator. I assume the compiler was unhappy about the 0.
complaining about zero width and unknown conversion type.
CodePudding user response:
I know C has
%0.*s
…
No, it does not. For sscanf
, the way to limit the number of characters accepted is to give the width as a decimal numeral after the %
, without 0
or .
, as in "%3s"
. It must be an actual numeral; it cannot be *
as in printf
, which specifies that the number is passed as an argument.
To use this with the [
conversion specifier, you would use "D[^,]"
.
If the maximum move title length is 44 characters, then the array that holds them as a string should be declared as char movieTitle[MAX_TITLE_CHARS 1];
to allow for a terminating null character.
If you want to parameterize the sscanf
string based on the symbol MAX_TITLE_CHARS
, so that it adapts if the value is changed, you can do this by defining MAX_TITLE_CHARS
as a macro instead of a const int
object:
#define MAX_TITLE_CHARS 44
and defining macros to convert a parameter into a string:
// Two macros are needed due to the order of operations in macro replacement.
#define ExpandAndStringize(x) #x
#define Stringize(x) ExpandAndStringize(x)
and using them:
sscanf(currentline,"%[^,],%" Stringize(MAX_TITLE_CHARS) "[^,],%[^,]", movieTime, movieTitle, movieRating);