How to enter two strings together with gets(); - string

I was wondering if there is a way to enter a string together like how we enter cin>>a>>b;
How can we do the same using gets for strings?

This is three months late, but it's probably worth writing since the only other answer is wildly off.
First, and most importantly, don't use gets(). There is no way to use it safely: it might as well be called overrun_my_buffer_and_crash_my_program_if_I_am_lucky(). There's a reason it's been removed from the latest C standard.
Second, cin >> a >> b; reads two whitespace-delimited strings, such as two words in a sentence. gets() and its much safer cousin fgets() read in a whole line, delimited by the newline character '\n' (note that they do not stop at other whitespace characters!). It is therefore much harder to replicate the behavior of cin - you'll have to do all the parsing yourself. (This is not saying it can't be done; if you have to do it in C, checkout strtok()).
The C equivalent of cin >> a >> b; is scanf(): char a[80], b[80]; scanf("%79s %79s", a, b); However, note that you can only read in strings up to a fixed maximum length (in this example 79 characters). It's fairly complicated to safely read in a string of arbitrary length in C; you'll need to read them in fixed-size chunks, and allocate sufficient memory to combine the chunks together.

If your input strings are separated with some sort of whitespace (i.e. " ", "\n" etc.), then it will simply be:
gets(s1);
gets(s2);
Another way is to use an fgets(char* str, int num, FILE* stream). It can be used twice for str1 and str2, and will take an input from stream into string until either num-1 chars was read, or eos ("\n", "\t", etc.) is reached. This function is strongly recommended, as it is more safe, than gets.
There also is a third, much more complicated way of doing this: you can define your own string class (inherited from std::string), and define an operator there, which will be standing for gets() or fgets(); but this option is really too complicated and unuseful for your situation.
If it is necessary for you to use one function, then you can create an overloaded gets() for two strings:
void gets(char * str1, char * str2)
{
gets(str1);
gets(str2);
}
The same trick can be done with fgets. But again, isn't it too complicated for you just to make 2 calls of gets() or fgets()?

Related

(F)Lex checking symbol without "consuming" it

The purpose of this is to concatenate strings (with (f)lex if possible) if they're written consecutively separated only by whitespace.
Strings start and end with "s.
The thing is I used states and while it can concatenate the strings it also consumes the next character/symbol that comes right after the strings.
For example -- "this " "is only " "1 string"id -- this will concatenate the strings ("this is only 1 string") but it will also "consume" the i in id thus destroying one token.
Is there a way to check the next char/symbol without actually "consuming/disposing" (can't really think of a term) it.
\" yy_push_state(X_STRING); yylval.s = new std::string("");
<X_STRING>\" yy_push_state(X_CONC);
<X_STRING>. yylval.s += yytext;
<X_STRING>\n yyerror("newline in string");
<X_CONC>[ ^\n] ;
<X_CONC>\" yy_pop_state();
<X_CONC>. yy_pop_state(); yy_pop_state(); return STRING
Any way to do it?
You can use yyless(0) to cause the current token to be rescanned. Make sure you change start condition, or you'll end up with an endless loop.
By the way, I think your code would be more readable if you switched start conditions with BEGIN rather than using the state stack. In fact, you could easily avoid start conditions, but that would make interpreting escape sequences more complicated. Possibly better would be to just avoid X_CONC by using a rule for \"[[:space:]]*\"

Parsing strings in Fortran

I am reading from a file in Fortran which has an undetermined number of floating point values on each line (for now, there are about 17 values on a line). I would like to read the 'n'th value on each line to a given floating point variable. How should i go about doing this?
In C the way I wrote it was to read the entire line onto the string and then do something like the following:
for(int il = 0; il < l; il++)
{
for(int im = -il; im <= il; im++)
pch = strtok(NULL, "\t ");
}
for(int im = -l; im <= m; im++)
pch = strtok(NULL, "\t ");
dval = atof(pch);
Here I am continually reading a value and throwing it away (thus shortening the string) until I am ready to accept the value I am trying to read.
Is there any way I can do this in Fortran? Is there a better way to do this in Fortran? The problem with my Fortran code seems to be that read(tline, '(f10.15)') tline1 does not shorten tline (tline is my string holding the entire line and tline1 what i am trying to parse it into), thus I cannot use the same method as I did in my C routine.
Any help?
The issue is that Fortran is a record-based I/O system while C is stream-based.
If you have access to a Fortran 2003 compliant compiler (modern versions of gfortran should work), you can use the stream ACCESS specifier to do what you want.
An example can be found here.
Of course, if you were really inclined, you could just use your C function directly from Fortran. Interfacing the two languages is generally simple, typically only requiring a wrapper with a lowercase name and an appended underscore (depending on compiler and platform of course). Passing arrays or strings back and forth is not so trivial typically; but for this example that wouldn't be needed.
Once the data is in a character array, you can read it into another variable as you are doing with the ADVANCE=no signature, ie.
do i = 1, numberIWant
read(tline, '(F10.15)', ADVANCE="no") tline1
end do
where tline should contain your number at the end of the loop.
Because of the record-based I/O, a READ statement will typically throw out what is after the end of the record. But the ADVANCE=no tells it not to.
If you know exactly at what position the value you want starts, you can use the T edit descriptor to initiate the next read from that position.
Let's say, for instance, that the width of each field is 10 characters and you want to read the fifth value. The read statement will then look something like the following.
read(file_unit, '(t41, f10.5)') value1
P.s.: You can dynamically create a format string at runtime, with the correct number after the t, by using a character variable as format and use an internal file write to put in this number.
Let's say you want the value that starts at position n. It will then look something like this (I alternated between single and double quotes to try to make it more clear where each string starts and stops):
write(my_format, '(a, i0, a)') "(t", n, ', f10.5)'
read(file_unit, my_format) value1

Reading a string with spaces in Fortran

Using read(*,*) in Fortran doesn't seem to work if the string to be read from the user contains spaces.
Consider the following code:
character(Len = 1000) :: input = ' '
read(*,*) input
If the user enters the string "Hello, my name is John Doe", only "Hello," will be stored in input; everything after the space is disregarded. My assumption is that the compiler assumes that "Hello," is the first argument, and that "my" is the second, so to capture the other words, we'd have to use something like read(*,*) input1, input2, input3... etc. The problem with this approach is that we'd need to create large character arrays for each input, and need to know exactly how many words will be entered.
Is there any way around this? Some function that will actually read the whole sentence, spaces and all?
character(100) :: line
write(*,'("Enter some text: ",\)')
read(*,'(A)') line
write(*,'(A)') line
end
... will read a line of text of maximum length 100 (enough for most practical purposes) and write it out back to you. Modify to your liking.
Instead of read(*, *), try read(*, '(a)'). I'm no Fortran expert, but the second argument to read is the format specifier (equivalent to the second argument to sscanf in C). * there means list format, which you don't want. You can also say a14 if you want to read 14 characters as a string, for example.

Modifying a character in a string in Lua

Is there any way to replace a character at position N in a string in Lua.
This is what I've come up with so far:
function replace_char(pos, str, r)
return str:sub(pos, pos - 1) .. r .. str:sub(pos + 1, str:len())
end
str = replace_char(2, "aaaaaa", "X")
print(str)
I can't use gsub either as that would replace every capture, not just the capture at position N.
Strings in Lua are immutable. That means, that any solution that replaces text in a string must end up constructing a new string with the desired content. For the specific case of replacing a single character with some other content, you will need to split the original string into a prefix part and a postfix part, and concatenate them back together around the new content.
This variation on your code:
function replace_char(pos, str, r)
return str:sub(1, pos-1) .. r .. str:sub(pos+1)
end
is the most direct translation to straightforward Lua. It is probably fast enough for most purposes. I've fixed the bug that the prefix should be the first pos-1 chars, and taken advantage of the fact that if the last argument to string.sub is missing it is assumed to be -1 which is equivalent to the end of the string.
But do note that it creates a number of temporary strings that will hang around in the string store until garbage collection eats them. The temporaries for the prefix and postfix can't be avoided in any solution. But this also has to create a temporary for the first .. operator to be consumed by the second.
It is possible that one of two alternate approaches could be faster. The first is the solution offered by PaĆ­lo Ebermann, but with one small tweak:
function replace_char2(pos, str, r)
return ("%s%s%s"):format(str:sub(1,pos-1), r, str:sub(pos+1))
end
This uses string.format to do the assembly of the result in the hopes that it can guess the final buffer size without needing extra temporary objects.
But do beware that string.format is likely to have issues with any \0 characters in any string that it passes through its %s format. Specifically, since it is implemented in terms of standard C's sprintf() function, it would be reasonable to expect it to terminate the substituted string at the first occurrence of \0. (Noted by user Delusional Logic in a comment.)
A third alternative that comes to mind is this:
function replace_char3(pos, str, r)
return table.concat{str:sub(1,pos-1), r, str:sub(pos+1)}
end
table.concat efficiently concatenates a list of strings into a final result. It has an optional second argument which is text to insert between the strings, which defaults to "" which suits our purpose here.
My guess is that unless your strings are huge and you do this substitution frequently, you won't see any practical performance differences between these methods. However, I've been surprised before, so profile your application to verify there is a bottleneck, and benchmark potential solutions carefully.
You should use pos inside your function instead of literal 1 and 3, but apart from this it looks good. Since Lua strings are immutable you can't really do much better than this.
Maybe
"%s%s%s":format(str:sub(1,pos-1), r, str:sub(pos+1, str:len())
is more efficient than the .. operator, but I doubt it - if it turns out to be a bottleneck, measure it (and then decide to implement this replacement function in C).
With luajit, you can use the FFI library to cast the string to a list of unsigned charts:
local ffi = require 'ffi'
txt = 'test'
ptr = ffi.cast('uint8_t*', txt)
ptr[1] = string.byte('o')

Basics of Strings

Ok, i've always kind of known that computers treat strings as a series of numbers under the covers, but i never really looked at the details of how it works. What sort of magic is going on in the average compiler/processor when we do, for instance, the following?
string myString = "foo";
myString += "bar";
print(myString) //replace with printing function of your choice
The answer is completely dependent on the language in question. But C is usually a good language to kind of see how things happen behind the scenes.
In C:
In C strings are array of char with a 0 at the end:
char str[1024];
strcpy(str, "hello ");
strcpy(str, "world!");
Behind the scenes str[0] == 'h' (which has an int value), str[1] == 'e', ...
str[11] == '!', str[12] == '\0';
A char is simply a number which can contain one of 256 values. Each character has a numeric value.
In C++:
strings are supported in the same way as C but you also have a string type which is part of STL.
string literals are part of static storage and cannot be changed directly unless you want undefined behavior.
It's implementation dependent how the string type actually works behind the scenes, but the string objects themselves are mutable.
In C#:
strings are immutable. Which means you can't directly change a string once it's created. When you do += what happen is a new string gets created and your string now references that new string.
The implementation varies between language and compiler of course, but typically for C it's something like the following. Note that strings are essentially syntactical sugar for char arrays (char[]) in C.
1.
string myString = "foo";
Allocate 3 bytes of memory for the array and set the value of the 1st byte to 'f' (its ASCII code rather), the 2nd byte to 'o', the 2rd byte to 'o'.
2.
foo += "bar";
Read existing string (char array) from memory pointed to by foo.
Allocate 6 bytes of memory, fill the first 3 bytes with the read contents of foo, and the next 3 bytes with b, a, and r.
3.
print(foo)
Read the string foo now points to from memory, and print it to the screen.
This is a pretty rough overview, but hopefully should give you the general idea.
Side note: In some languages/compuilers, char != byte - for example, C#, where strings are stored in Unicode format by default, and notably the length of the string is also stored in memory. C++ typically uses null-terminated strings, which solves the problem in another way, though it means determining its length is O(n) rather than O(1).
Its very language dependent. However, in most cases strings are immutable, so doing that is going to allocate a new string and release the old one's memory.
I'm assuming a typo in your sample and that there is only one variable called either foo or myString, not two variables?
I'd say that it'll depend a lot on what compiler you're using. In .Net strings are immutable so when you add "bar" you're not actually adding it but rather creating a new string containing "foobar" and telling it to put that in your variable.
In other languages it will work differently.

Resources