BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Patrick
Opal | Level 21

Hi all,

I'm using fget() to read records from an external file into a SAS variable. Everything works except that leading blanks aren't kept (=string in SAS variable starts with first non-blank character). 

Any help how to keep the leading blanks would be really appreciated. I simply can't make it work.

 

Below self contained code sample showcasing the challenge. 

 

1. Create sample file

%let source_file=%sysfunc(pathname(work))\myscript.sas;
data _null_;
  infile datalines truncover;
  file "&source_file";
  input;
  put _infile_;
  datalines4;
data sample;
  set sashelp.class;
run;
;;;;

 

2. Syntax reading the sample file that keeps the leading blanks

data _null_;
  file print;
  infile "&source_file" lrecl=132;
  input;
  put _infile_;
run;

Patrick_2-1621158037101.png

 

3. Syntax using fget() that doesn't keep the leading blanks

/* here the code I want to use BUT need to keep leading blanks from source file */
data _null_;
  file print;
  length _filrf $8 _instr $132;
  informat _instr $char132.;
  _filrf='demo';
  _rc=filename(_filrf, cats("&source_file"));                                                                                  
  _fid=fopen(_filrf);   
  if _fid > 0 then                                                                                                                     
    do while(fread(_fid)=0);                                                                                                  
      _rc=fget(_fid, _instr, 132);
      put _instr;                                                                                                                             
    end;                                                                                                                                 
  _rc=fclose(_fid);                                                                                                        
  _rc=filename(_filrf);
run;

Patrick_1-1621158004863.png

 

The real problem I need to solve

I've got a set of main programs with %includes to other programs - and the %included programs can have further %includes ("cascading %includes")

I want to get rid of the includes by creating new main programs that got all the %included code directly in the main script.

 

I've got a working solution using #3 syntax but it's not acceptable to loose all the code indention when generating the new scripts. 

 

Should there be no solution to keep the leading blanks with my approach then I take accept more than happily also other coding approaches that solve my actual problem. 

 

The solution needs to work under Windows and Unix. That's why I went for an approach using SAS.

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
FreelanceReinh
Jade | Level 19

Hi @Patrick,

 

I think FGET did read the leading blanks. It's just that the PUT statement using list PUT didn't write them. With formatted PUT, e.g.

put _instr $132.;

they appear.

 

Edit: Also, the INFORMAT statement doesn't seem to be necessary.

View solution in original post

9 REPLIES 9
Ksharp
Super User

Using informat $char. :

 

 

%let source_file=%sysfunc(pathname(work))\myscript.sas;
data _null_;
  infile datalines truncover;
  file "&source_file";
  input x $char100.;
  put x $char100.;
  datalines4;
data sample;
  set sashelp.class;
run;
;;;;
Patrick
Opal | Level 21

Hi @Ksharp 

You probably haven't really read the whole question?

Writing the sample file works and is not the issue/question asked. It's about reading the sample file using data step functions. Because I want to read .sas files with %include statements and create a single .sas files with all the code as result, I have switch the external file whenever I encounter an %include, read the whole %included file, and then switch back to the main programs and continue reading the records after the %include statement. That's why I'm using data step functions also to define and open the external file.

Thanks,

Patrick

Ksharp
Super User
Patrick,
Sorry. I have no time to go through this question.
There are some many post everyday at sas communities.So I just pay a few second to read a post .

Best !
Xia Ke Shan
Patrick
Opal | Level 21

@Ksharp 

Then may-be just answer questions where you can spend the necessary time for reading and understanding the problem. 

I believe I've got sufficient experience to decide what answers get me further but you might send beginners on the wrong path if not really addressing their problem.

Ksharp
Super User
@Patrick
I would like to spend more time. But I have only 1 or 2 hours to stay here.
And Fortunately ,In most posts OP would post the output he want see,so I can compare it with my code.
So you still in your original company ? and still in Australia ?
FreelanceReinh
Jade | Level 19

Hi @Patrick,

 

I think FGET did read the leading blanks. It's just that the PUT statement using list PUT didn't write them. With formatted PUT, e.g.

put _instr $132.;

they appear.

 

Edit: Also, the INFORMAT statement doesn't seem to be necessary.

Patrick
Opal | Level 21

@FreelanceReinh 

Thank you so much! Tried so many things but not this very simple one.

Do you also have an explanation why using an explicit format has this effect?

 

True, the informat has no effect. I've only added it to the sample code so no one is going to propose it....

FreelanceReinh
Jade | Level 19

@Patrick wrote:

Do you also have an explanation why using an explicit format has this effect?


This is one of the differences between formatted output and list output. The documentation of the latter says in section "Using List Output":

"Character values are left-aligned in the field; leading and trailing blanks are removed. To include blanks (in addition to the blank inserted after each value), use formatted or column output instead of list output."

Patrick
Opal | Level 21

Thank you very much @FreelanceReinh  - Learned something 🙂 

I believe I was so far only fully aware of the different styles for reading external data but not for writing it.

 

I've ended up using format &varying. to not pad all the records with up to 132 blanks.

data _null_;
  file print;
  length _filrf $8 _instr $132;
  informat _instr $char132.;
  _filrf='demo';
  _rc=filename(_filrf, cats("&source_file"));                                                                                  
  _fid=fopen(_filrf);   
  if _fid > 0 then                                                                                                                     
    do while(fread(_fid)=0);                                                                                                  
      _rc=fget(_fid, _instr, 132);
      _l=lengthn(_instr);
      put _instr $varying. _l;                                                                                                                             
    end;                                                                                                                                 
  _rc=fclose(_fid);                                                                                                        
  _rc=filename(_filrf);
run;

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 762 views
  • 1 like
  • 3 in conversation