Read only first word of line from line with $fscanf()

Hi,

I would like to know whether it is possible or not read just the first word from line with $fscanf() as placed below

$fscanf(fd, "%s%*[^\n]", str);

In C++, that statement (%s%*[^\n]) reads just the first word from line, store the word to str and throw away rest up to a new line. Is that kind of syntax supported in SystemVerilog, I think no after a couple of check in simulation? Any alternative SystemVerilog dedicated syntax to do that?

Thanks

Vaino

In reply to Vaino:

Just %s is sufficient in this case.


$fscanf(fd, "%s", str); // Read from line start till encountering a whitespace.

In reply to ayehia:

No,

%s is definitely NOT sufficient in my case.

I have text file including a random amount of columns up to ten pieces. Those columns are separated with white space characters (blanks or tabs). Inside my scoreboard, I am only interested about the first column (i.e. first word) of the line. Text file is for example as follows:

sss sss sss sss ssss

That’s why I wanna just use syntax I typed in my first post to this thread. I want also sideline $sscanf() function as it adds redundancy since $fgets() need to called before $sscanf() to get line as string input for the scan function. So, please give info if you know how “%s%*[^\n]” syntax should be interpreted in SV. I think $fscanf() is imported mostly from C language’s fscanf, so why that syntax is tackled?

-Vaino

In reply to Vaino:

Then what you want is something like:


      string line;
      string first_word_column [];
      fd = $fopen ("myfile.txt", "r");
      while (!$feof(fd)) begin
          code = $fgets (line, fd); //Get entire line
          code = $sscanf (line, "%s", first_word_column[i]); //Get first word of that line
          i++;
      end
      $fclose (fd);

In reply to ayehia:

No, that is not what I want to see. As I stated already a couple of times, I would like to execute read operation with C-style onliner using $fscanf() as

$fscanf(fd, "%s%*[^\n]", str);

Not with loop construct you proposed.

SystemVerilog agrees * assignment character

$fscanf(fd, "%s%*s", str);  // == read two consecutive words but don't assign the second one just the first one (please refer to LRM to see more info on that)

So, I am repeating myself again to ask how this C-style “%s%*[^\n]” syntax should typed in SystemVerilog style if possible? I am not finding any loop construct to overcome this, those constructs are obvious already.

In reply to Vaino:

The specification for the formatting string in SystemVerilog is very basic, but there are backward compatibility issues that prevent extending it to match the C++ formatting capabilities directly. The only way to access the exact formatting capabilities of C++ is to import the routines through the DPI.

In reply to dave_59:

Hi Dave,

That’s was very much the answer I was looking for, thanks. As you stated backward compatibility issues, is the SystemVerilog LRM committee working with those for the future generation of SystemVerilog? BTW, if trying to import C++ fscanf through DPI, how that should be typed practically, probably something starting with

import "DPI-C" function int fscanf(int fd, string format, ...); // ???
  • Vaino

In reply to Vaino:
The IEEE SystemVerilog committee has been inactive for the last 3 years, but is now just starting up. It would be very difficult to get the same behavior as C++ since Verilog, and now SystemVerilog have different meanings for things like %h.

The DPI has limitations that makes importing fscanf() directly a problem. You cannot import a routine having variable numbers of arguments with arbitrary types. So you will need to write a C wrapper around fscanf() for each use case.