Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

scan commnad 1

Status
Not open for further replies.

motel

Technical User
Jul 6, 2001
3
IN
scan command does not read more than 20 fields. Does any one know about he workaround to this problem

my scan commnad looks like this.
scan $line {%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,]} var1,var2,var3,var4,var5,var6,var7,var8,var9,var10,var11,var12,var13,var14,var15,var16,var17,var18,var19,var20,var21

the error it says is too many fields to scan.

regards,
motel
 
Well, I must admit that I'd never tried writing a scan command with more than 20 conversion specifiers. But I went ahead and tried out your example, which worked after I'd made a little correction to it. You separated all of the variable names with commas; Tcl is a whitespace-separated language. Once I had replaced your commas with spaces, scan worked fine.

But let's dig a little deeper. Looking at your scan pattern, it looks as though you're trying to parse comma-separated values (CSV data). There's a much easier way of doing this than with the scan command: split. The syntax is:

split string ?delimiters?

split splits a string into a list given the delimiter character(s) you specify. (If you don't specify delimiters, split splits on any whitespace character.) The return value is the resulting list. Thus, to split your CSV data:

Code:
set vals [split $line ","]

Then, to test if the data had 21 CSV elements:

Code:
if {[llength $vals] != 21} {
    puts stderr "Invalid data"
}

By the way, Tcl also has a join command that concatenates the elements of a list given a specified delimter string:

join list ?delimiters?

Thus, to generate CSV data from a list:

Code:
set csv [join $list ","]

I suspect that you'll find the data easier to wrangle by keeping it in list format, and just using list commands like lindex to grab particular values from it. However, if you really want to split of your list, you can do:

Code:
foreach { val1  val2  val3  val4  val5                 val6  val7  val8  val9 val10                val11 val12 val13 val14 val15                val16 val17 val18 val19 val20               val21 } $vals { break }

Or, more cleverly but less efficiently:

Code:
set i 1
foreach val $vals {
    set val$i $val
    incr i
}

- Ken Jones, President
Avia Training and Consulting
866-TCL-HELP (866-825-4357) US Toll free
415-643-8692 Voice
415-643-8697 Fax
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top