va_list not working properly - variadic-functions

I have written a code:
void xy(int a,...)
{
va_list list;
va_start(list,a);
int result=0;//va_start(list,x);
for(;;)
{
int p=va_arg(list,int);
cout<<p<<endl;
if(p==0)
break;
result+=p;
}
va_end(list);
cout<<result<<endl;
}
and called this function :
xy(20,30,40);
I am expecting 20, 30, 40 will be printed. and their sum. but it is printing :
30
40
13336564
11872144
-3271312
-3271224
12029596
11926688
134527888
-3271224
12029596
1
-3271180
-3271172
11929640
0
191296075
don't know why.
Please suggest some solution.

Well, your code is really clever, isn't it? You are checking for a zero to mark the end of the parameter list. However, you are calling the function with a parameter list that doesn't end with or contain a zero. Where do you think would the zero come from that you are checking? Call instead
xy (20, 30, 40, 0);
bluebell's comment is obviously nonsense. THERE IS NO WAY TO DETECT THAT THERE ARE NO MORE ARGUMENTS. Caller and callee have to agree how to detect the end of the argument list, and then of course the caller has to send the write parameters.
printf does this by the caller sending a format string that the printf function will examine. Or you could send the number of arguments as the first parameter, so a function calculating the average of n values could be called as
average (1, 3.7);
average (3, 3.7, 4.1, 4.2);
20 is not printed because 20 is sent as the named argument, so your sum should start with the value a. 30 and 40 are received through the va_arg macro, as will be the number 0 if you pass it as a parameter - if you don't pass that number, your code will continue reading data from random memory locations until by chance it reads memory containing a number 0.
As another example: When you call printf ("%d %d\n", 4, 5); the printf function gets the format string "%d %d\n" as the first parameter. It examines this string and finds the letters %d twice, so it means there must be two int parameters. If you didn't supply two int parameters, you would expect rubbish to be printed.

Related

dealing with array of characters . how can i define an array without declaring its size?

I have an assignment to write a c++ program that:
declares an array named gamma of type char.
declares an array named vowels of type char.
prompts the user to input n characters in the array gamma.
defines a function named save vowels that determines and return the number of vowels letters in the gamma array and save them in the vowels array.
I already tried to write this but I got many errors especially with gamma array.
#include<iostream>
using namespace std;
void main()
{
char gamma[];
int i;
cout<<"insert characterst//insert -1 when you finish "<<endl;
while(i!=-1)
{
cin>>i;
gamma[]='i';
}
char vowels[]={'a','e','i','o','u'};}
You look to be well on your way.
declares an array named gamma of type char.
char gamma[];
This part is almost correct although the array has a size of 0. If you wanted to give it a size of 10, you would change it to
char gamma[10];
declares an array named vowels of type char.
This part is fine as is.
char vowels[]={'a','e','i','o','u'};
The list automatically gives vowels a size of 5 and assigns the values.
prompts the user to input n characters in the array gamma.
You look to have this down perfectly with the cout/cin lines. One small nitpick is that you should prefer using "\n" at the end of a cout instead of endl as it is much faster.
cout << "insert characterst//insert -1 when you finish\n";
You also need to change how you write to your array. You have to specify the index in which you want to write.
gamma[0] = 3; // Set the first element of gamma to 3
gamma[2] = 11;// Set the third element of gamma to 11
You'll need to add a counter to your while loop to know which position of gamma you are writing to
int counter = 0;
while(...) {
cin >> i;
gamma[counter] = i;
counter++;
}
You also need to add a check to your while loop that makes sure you don't write past the end of your gamma array. This is likely the cause of your errors.
For example, if we gamma is defined with a size of 10 it can only hold 10 characters. Trying to write 11 characters to gamma will likely cause the program to crash. Try adding a check like:
while( i != -1 && counter < 10) // where 10 is capacity of gamma
defines a function named save vowels that determines and return the number of vowels letters in the gamma array and save them in the vowels array.
You didn't give anything in your question on this point so I can't really help you out here.

find number of repeating substrings in a string

I am looking for an algorithm that will find the number of repeating substrings in a single string.
For this, I was looking for some dynamic programming algorithms but didn't find any that would help me. I just want some tutorial on how to do this.
Let's say I have a string ABCDABCDABCD. The expected output for this would be 3, because there is ABCD 3 times.
For input AAAA, output would be 4, since A is repeated 4 times.
For input ASDF, output would be 1, since every individual character is repeated 1 time only.
I hope that someone can point me in the right direction. Thank you.
I am taking the following assumptions:
The repeating substrings must be consecutive. That is, in case of ABCDABC, ABC would not count as a repeating substring, but it would in case of ABCABC.
The repeating substrings must be non-overalpping. That is, in case of ABCABC, ABC would not count as a repeating substring.
In case of multiple possible answers, we want the one with the maximum value. That is, in the case of AAAA, the answer should be 4 (a is the substring) rather than 2 (aa is the substring).
Under these assumptions, the algorithm is as follows:
Let the input string be denoted as inputString.
Calculate the KMP failure function array for the input string. Let this array be denoted as failure[]. This operation if of linear time complexity with respect to the length of the string. So, by definition, failure[i] denotes the length of the longest proper-prefix of the substring inputString[0....i] that is also a proper-suffix of the same substring.
Let len = inputString.length - failure.lastIndexValue. At this point, we know that if there is any repeating string at all, then it has to be of this length len. But we'll need to check for that; First, just check if len perfectly divides inputString.length (that is, inputString.length % len == 0). If yes, then check if every consecutive (non-overlapping) substring of len characters is the same or not; this operation is again of linear time complexity with respect to the length of the input string.
If it turns out that every consecutive non-overlapping substring is the same, then the answer would be = inputString.length/ len. Otherwise, the answer is simply inputString.length, as there is no such repeating substring present.
The overall time complexity would be O(n), where n is the number of characters in the input string.
A sample code for calculating the KMP failure array is given here.
For example,
Let the input string be abcaabcaabca.
Its KMP failure array would be - [0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8].
So, our len = (12 - 8) = 4.
And every consecutive non-overlapping substring of length 4 is the same (abca).
Therefore the answer is 12/4 = 3. That is, abca is repeated 3 times repeatedly.
The solution for this with C# is:
class Program
{
public static string CountOfRepeatedSubstring(string str)
{
if (str.Length < 2)
{
return "-1";
}
StringBuilder substr = new StringBuilder();
// Length of the substring cannot be greater than half of the actual string
for (int i = 0; i < str.Length / 2; i++)
{
// We will iterate through half of the actual string and
// create a new string by appending the current character to the previous character
substr.Append(str[i]);
String clearedOfNewSubstrings = str.Replace(substr.ToString(), "");
// We will remove the newly created substring from the actual string and
// check if the length of the actual string, cleared of the newly created substring, is 0.
// If 0 it tells us that it is only made of its substring
if (clearedOfNewSubstrings.Length == 0)
{
// Next we will return the count of the newly created substring in the actual string.
var countOccurences = Regex.Matches(str, substr.ToString()).Count;
return countOccurences.ToString();
}
}
return "-1";
}
static void Main(string[] args)
{
// Input: {"abcdaabcdaabcda"}
// Output: 3
// Input: { "abcdaabcdaabcda" }
// Output: -1
// Input: {"barrybarrybarry"}
// Output: 3
var s = "asdf"; // Output will be -1
Console.WriteLine(CountOfRepeatedSubstring(s));
}
}
How do you want to specify the "repeating string"? Is it simply the first group of characters up until either a) the first character is found again, b) the pattern begins to repeat, or c) some other criteria?
So, if your string is "ABBAABBA", is that a 2 because "ABBA" repeats twice or is it 1 because you have "ABB" followed by "AAB"? What about "ABCDABCE" -- does "ABC" count (despite the "D" in between repetitions?) In "ABCDABCABCDABC", is the repeating string "ABCD" (1) or "ABCDABC" (2)?
What about "AAABBAAABB" -- is that 3 ("AAA") or 2 ("AAABB")?
If the end of the repeating string is another instance of the first letter, it's pretty simple:
Work your way through the string character by character, putting each character into another variable as you go, until the next character matches the first one. Then, given the length of the substring in your second variable, check the next bit of your string to see if it matches. Continue until it doesn't match or you hit the end of the string.
If you just want to find any length pattern that repeats regardless of whether the first character is repeated within the pattern, it gets more complicated (but, fortunately, it's the sort of thing computers are good at).
You'll need to go character by character building a pattern in another variable as above, but you'll also have to watch for the first character to reappear and start building a second substring as you go, to see if it matches the first. This should probably go in an array as you might encounter a third (or more) instance of the first character which would trigger the need to track yet another possible match.
It's not difficult but there is a lot to keep track of and it's a rather annoying problem. Is there a particular reason you're doing this?

strange character in Fortran write output

I want to time some subroutines. Here is the template I use to write the name and duration of execution:
SUBROUTINE get_sigma_vrelp
...declarations...
real(8) :: starttime, endtime
CHARACTER (LEN = 200) timebuf
starttime = MPI_Wtime()
...do stuff...
endtime = MPI_Wtime()
write (timebuf, '(30a,e20.10e3)') 'get_sigma_vrelp',endtime-starttime
call pout(timebuf)
END SUBROUTINE get_sigma_vrelp
And here is a sample output:
(thread 4):get_sigma_vrelp �>
Why is a strange character printed instead of a numerical value for endtime-starttime? Incidentally, pout() simply writes the buffer to a process-specific file in a threadsafe manner. It shouldn't have anything to do with the problem, but if there is nothing else here that would cause the erroneous output then I can post its body.
You have it the wrong way round! The line should read
write (timebuf, '(a30,e20.10e3)') 'get_sigma_vrelp',endtime-starttime
This way, you expect one string that is 30 characters long (a30) instead of 30 strings of arbitrary length (30a). The write statement does not receive characters after the first string, but the corresponding bytes of the float. Hence the garbage.
Your character literal is only 15 chars long, so you could write the line as
write (timebuf, '(a15,e20.10e3)') 'get_sigma_vrelp',endtime-starttime
or let the compiler decide the length on its own:
write (timebuf, '(a,e20.10e3)') 'get_sigma_vrelp',endtime-starttime

Comparison between strings and integers in matlab

I am doing some classification and needed to convert an integer code to strings for that reason. I wrote something like this:
s(1).class = 1;
s(2).class = 7;
s(3).class = 9;
[s([find([s.class] == 1)]).class] = deal('c1'); %first conversion
[s([find([s.class] > 1)]).class] = deal('c2'); %second conversion
and was surprised to find s being a 1x4 struct array after the second conversion instead of the expected 1x3 struct array with the values.
Now, after some research, I understand that after the first conversion the value of s(1).class is 'c1' and the argument to find in the second conversion is not what I assumed it would be. The [s.class] statement actually returns something like the string 'c1\a\t' with ASCII escape sequences for bell and horizontal tab.
As the comparison does work (returning the matrix [1 1 1 1] and thus expanding my structure) I assume that matlab converts either the operand [s.class] or the operand 1.
Which is it? What actually is compared here numbers or characters?
And on the other hand is there a built in way to make > more restrictive, i. e. to require the operands to be of the same type and if not to throw an error?
When you do the comparison 'ab' > 1, the char array 'ab' gets converted to a double array, namely the ASCII codes of the characters. So 'ab' > 1 is equivalent to double('ab') > 1, which gives [1 1].
To get the behaviour you want (issue an error if one of the arguments is char) you could define a function:
function z = greaterthan(x,y)
if ischar(x) || ischar(y)
error('Invalid comparison: one of the input arguments is of type char')
else
z = x>y;
end
so that
>> greaterthan([0 1 2], 1)
ans =
0 0 1
>> greaterthan('ab', 1)
??? Error using ==> greaterthan at 3
Invalid comparison between char and int
Because you have not provided any expected output yet, I am going with the observations.
You are using a comprehension method (by invoking find) to determine which locations you will be populating for struct s with the results from your method deal (takes the argument c1 and c2). You have already set your type for s{whatever).class in the first snippet you provided. Which means it is number you are comparing, not character.
There is this isa function to see which class your variable belongs to. Use that to see what it is you are actually putting in (should say int32 for your case).

Convert an integer to a string

I am trying to learn assembler and want to write a function to convert a number to a string. The signature of the function I want to write would looks like this in a C-like fashion:
int numToStr(long int num, unsigned int bufLen, char* buf)
The function should return the number of bytes that were used if conversion was successful, and 0 otherwise.
My current approach is a simple algorithm. In all cases, if the buffer is full, return 0.
Check if the number is negative. If it is, write a - char into buf[0] and increment the current place in the buffer
Repeatedly divide by 10 and store the remainders in the buffer, until the division yields 0.
Reverse the number in the buffer.
Is this the best way to do this conversion?
This is pretty much how every single implementation of itoa that I've seen works.
One thing that you don't mention but do want to take care of is bounds checking (i.e. making sure you don't write past bufLen).
With regards to the sign: once you've written the -, you need to negate the value. Also, the - needs to be excluded from the final reversal; an alternative is to remember the sign at the start but only write it at the end (just before the reversal).
One final corner case is to make sure that zero gets written out correctly, i.e. as 0 and not as an empty string.

Resources