I have following C code for handling strings
#define SECRET_TOKEN_SIZE 33 /* [0..31] bytes random alpha numeric values + 32 byte for null character. */
#define TIME_STAMP_SIZE 32
/* build secret value */
char secretString[256] = {0};
char hpci_ws_secret_val[SECRET_TOKEN_SIZE] = {0};
char sessionId[SECRET_TOKEN_SIZE] = {0};
char secretSessionId[SECRET_TOKEN_SIZE] = {0};
char timeStamp[TIME_STAMP_SIZE] = {0};
int lenTimeStamp = strlen(recvtimestamp);
int lenWSSecret;
strcpy(hpci_ws_secret_val, hpciWebServerGetSecretVal());
strncpy(timeStamp, recvtimestamp, lenTimeStamp);
lenWSSecret = strlen(hpci_ws_secret_val);
printf("VRK ValidateActionToken web secret value %s length %d \n ", hpci_ws_secret_val, lenWSSecret );
printf("VRK ValidateActionToken time stamp %s length: %d \n ", timeStamp, lenTimeStamp);
/* site secret value + timestamp */
strncpy(secretString, hpci_ws_secret_val, SECRET_TOKEN_SIZE);
printf("VRK ValidateActionToken secretValue %s \n", secretString);
strncat(secretString, timeStamp, lenTimeStamp);
printf("VRK Valandtime %s \n", secretString);
GetSessionIds(reqId, sessionId, secretSessionId);
/* session id + secret session id */
printf("VRK ValidateActionToken sessionId %s \n ", sessionId);
printf("VRK ValidateActionToken secretSessionId %s \n ", secretSessionId);
strncat(secretString, sessionId, SECRET_TOKEN_SIZE );
strncat(secretString, secretSessionId, SECRET_TOKEN_SIZE);
unsigned char formDigestVal[SECRET_TOKEN_SIZE] = {0};
unsigned int mdlen = 0;
printf("VRK ValidateActionToken calculating MD5 for string %s \n ", secretString);
GetDigestValue("MD5", secretString, strlen(secretString), formDigestVal, &mdlen);
char strDigestVal[SECRET_TOKEN_SIZE] = {0};
ConvertRandomValToString(formDigestVal, strDigestVal, SECRET_TOKEN_SIZE );
Output:
VRK ValidateActionToken web secret value 75E87C8CE72767A63C47918AADED06CB length 32
length: 11 eActionToken time stamp 1669294822
VRK ValidateActionToken secretValue 75E87C8CE72767A63C47918AADED06CB
RK Valandtime 75E87C8CE72767A63C47918AADED06CB1669294822 ------------> secret and time stamp are appeneded correctly
VRK ValidateActionToken sessionId 92030F994ED20A91856E044C40B55F75
VRK ValidateActionToken secretSessionId 21ED81483883182FADE03128A478EEB0
VRK ValidateActionToken calculating MD5 for string 75E87C8CE72767A63C47918AADED92030F994ED20A91856E044C40B55F7521ED81483883182FADE03128A478EEB0 ---->Notice here last 4 bytes and time stamp are lost
Question: I am always observing last 4 bytes of secret value i.e., in this example "06CB" and time stamp is not shown in final string, but session id
and secret session is appending corretly. I tried to check memory corruption but to my knowledge corruption is not observed. Any mistake I am making?
By the way I have added printf statement after GetSessionIds, here printf is shown correctly as expected with timestamp. Another observation is that if I removed timestamp, string is appeneded correctly.
Thanks for your guidence and time.
75E87C8CE72767A63C47918AADED##last 4 bytes of secret value and time stamp is lost ###92030F994ED20A91856E044C40B55F7521ED81483883182FADE03128A478EEB0
Related
I'm using strptime(3) to parse a string representing a date:
#include <time.h>
#include <stdio.h>
int main () {
struct tm t;
strptime("2015-04-19 12:00:00", "%F %T", &t); /* Sunday */
printf("%d\n", t.tm_wday); /* Should print 0 */
return 0;
}
That date is a Sunday, according to the output of cal -y 2015. But when I compile this on OSX (presumably with clang) it prints 6:
$ gcc timetest.c ; ./a.out
6
whereas on Debian it prints the (correct) 0:
$ gcc timetest.c ; ./a.out
0
Any explanation for the difference?
UPDATE
Here is the same program, except that t is initialised with a valid time and I'm reporting the return value of strptime():
#include <time.h>
#include <stdio.h>
int main () {
time_t epoch = 0;
struct tm t;
char *ret;
t = *localtime(&epoch);
ret = strptime("2015-04-19 12:00:00", "%F %T", &t); /* Sunday */
printf("%d\n", t.tm_wday); /* Should print 0 */
printf("strptime() returned %p (%d)\n", ret, *ret);
return 0;
}
Here is the output:
$ gcc timetest.c ; ./a.out
6
strptime() returned 0x10c72af83 (0)
Here is the clang version I use:
$ clang -v
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.1.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
I think the reason is simply that, by design, the strptime function only sets the fields that appear in the format. Essentially, strptime(3) just parses fields from a given string using a supplied format into a referenced structure and performs no other computation or logic. Since your code uses the format %F %T then only the fields corresponding to %Y-%m-%d and %H:%M:%S (namely tm_{year,mon,mday,hour,min,sec}) are modified.
You can experiment by explicitly setting t.tm_wday to some known value that shouldn't by set by strptime (e.g. 123) and verify that it is not changed by that call. Note that you should probably initialize your struct tm before playing with it since any of those fields may contain random values, e.g. struct tm t; memset((void *) &t, 0, sizeof(t));.
Moreover, this Linux strptime(3) man page contains the following note which leads me to believe that the special behavior it describes is non-standard (though obviously desirable):
The glibc implementation does not touch those fields which are not explicitly specified, except that it recomputes the tm_wday and tm_yday field if any of the year, month, or day elements changed.
This answer shows how you can use the trio of strptime/mktime/localtime (or gmtime) to populate the tm.tm_wday field for dates after the UNIX epoch.
Following on from the observation in the comments, here's a program derived from your code which illustrates, even if it does not explain, what is going on:
#include <time.h>
#include <stdio.h>
static void dump_struct_tm(const char *tag, const struct tm *t)
{
printf("%s:\n", tag);
printf(" Time: %.2d:%.2d:%.2d ", t-> tm_hour, t->tm_min, t->tm_sec);
printf(" Date: %.4d-%.2d-%.2d\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
printf(" Wday: %d Yday: %.3d (DST %d Zone [%s] offset %ld)\n",
t->tm_wday, t->tm_yday, t->tm_isdst, t->tm_zone, t-> tm_gmtoff);
}
int main(void)
{
time_t epoch = 0;
struct tm t;
char *ret;
t = *localtime(&epoch);
dump_struct_tm("Epoch", &t);
putchar('\n');
ret = strptime("2015-04-19 12:00:00", "%F %T", &t);
dump_struct_tm("strptime()", &t);
time_t rt = mktime(&t);
dump_struct_tm("mktime()", &t);
printf("Weekday: %d\n", t.tm_wday);
printf("strptime() returned %p (%d)\n", ret, *ret);
printf("Unix time: %lld\n\n", (long long)rt);
t.tm_isdst = -1;
ret = strptime("2015-04-19 12:00:00", "%F %T", &t);
dump_struct_tm("strptime()", &t);
rt = mktime(&t);
dump_struct_tm("mktime()", &t);
printf("Weekday: %d\n", t.tm_wday);
printf("strptime() returned %p (%d)\n", ret, *ret);
printf("Unix time: %lld\n\n", (long long)rt);
return 0;
}
This analyzes the struct tm (as defined by the manual page on macOS Sierra) at different points. Note how the setting of tm_isdst alters the behaviour.
Epoch:
Time: 16:00:00 Date: 1969-12-31
Wday: 3 Yday: 364 (DST 0 Zone [PST] offset -28800)
strptime():
Time: 12:00:00 Date: 2015-04-19
Wday: 6 Yday: 108 (DST 0 Zone [(null)] offset -28800)
mktime():
Time: 13:00:00 Date: 2015-04-19
Wday: 0 Yday: 108 (DST 1 Zone [PDT] offset -25200)
Weekday: 0
strptime() returned 0x100c82f0c (0)
Unix time: 1429473600
strptime():
Time: 12:00:00 Date: 2015-04-19
Wday: 6 Yday: 108 (DST -1 Zone [(null)] offset -25200)
mktime():
Time: 12:00:00 Date: 2015-04-19
Wday: 0 Yday: 108 (DST 1 Zone [PDT] offset -25200)
Weekday: 0
strptime() returned 0x100c82f0c (0)
Unix time: 1429470000
I'm still not clear why strptime() mispopulates the tm_wday field, especially since it seems to get the tm_yday field correct. The 19th of April is day 108 of the year when the 1st of January is day 0.
So I have this text
today average human lifespan in Western countries is approaching and exceeding 80 years.
1 Japan 82.6 123 19
2 Hong Kong 82.2 234 411
3 Iceland 81.8 345 26
4 Switzerland 81.7 456 7
5 Australia 81.2 567 500
...
80 Lithuania 73.0 800 2
...
194 Swaziland 39.6 142 212
195 133714 18.0 133 998
196 100110011 10.0 667 87351
I need to round the float numbers in this text to whole numbers. I've searched a lot of forums but I cannot seem to find what I need.
This text is given in a .txt file. My task: "Round real number(that have decimals) to whole numbers. The corrected text should be in a new .txt" That's it.
scanf and sscanf are your best friend to extract anything of a string.
floor is use full to suppress decimal on a float. Then can be used to round it (to use it include math.h)...
The format string describes the expected format.The function return the number of parameters found.
Sample:
Initialization
int id = -1;
char country[160]; /* /!\ Warning country name length shall be fewer than 160 */
/* Scanf don't care of this array parameter length. If it is too short */
/* It will erase following memory... */
/* That is why scanf are often disparaging */
float percent = 0.0;
char a_number_as_string[10];
int other_number = -1;
char* Switzerland = "4 Switzerland 81.7654321 456 7";
effectif code
int ret = sscanf(Switzerland, "%d %s %f %s %d", &id, country,
&percent, a_number_as_string, &other_number);
if(ret == 5) {
printf("~~ id: %d\n\tcountry: %s\n\tpercent: %.2f\n\tand : "
"(%s, %d)\n", id, country, percent, a_number_as_string,
other_number);
/////// ROUND
printf("*** round");
printf("\twith printf %%.1f = %.1f\n", percent);
printf("\twith printf %%.2f = %.2f\n", percent);
printf("\twith printf %%.3f = %.3f\n", percent);
printf("\twith printf %%.4f = %.4f\n", percent);
printf("*** With floor (included in math.h)\n");
printf("\t1 decimal: %f\n", floor(percent*10)/10);
printf("\t2 decimal: %f\n", floor(percent*100)/100);
printf("\t3 decimal: %f\n", floor(percent*1000)/1000);
printf("\t4 decimal: %f\n", floor(percent*10000)/10000);
} else {
printf("--> ret = %d", ret);
}
output
~~ id: 4
country: Switzerland
percent: 81.70
and : (456, 7)
*** round
with printf %.1f = 81.8
with printf %.2f = 81.77
with printf %.3f = 81.765
with printf %.4f = 81.7654
*** With floor (included in math.h)
1 decimal: 81.700000
2 decimal: 81.760000
3 decimal: 81.765000
4 decimal: 81.765400
This function are describe in Unix, OSX, Unix terminal man pages:
man scanf
man sscanf
man floor
Or you can find it on several copies of this manages on the web for example
scanf
sscanf
floor
here is the program I have already tested it for a single line of input string:-
// LINK - http://stackoverflow.com/questions/40317323/how-to-extract-float-numbers-from-text-in-c#40317323
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
int main()
{
char s[100];
int i,j;
double sum=0.0,frac=0.0;
gets(s); // delimited by '\n' and not by ' '
for( i=0;s[i]!='\0';i++) // for finding index value of decimal point(.)
{
if(s[i]=='.')
break;
}
for(;s[i]!=' ';i--); // for changing key index value to the index value of the first space character(' ') before the decimal point(.)
i++;
for(i;s[i]!='.';i++)
{
sum=sum*10+(s[i]-48); // For extracting integer part
}
i++;
for(i,j=1;s[i]!=' ';i++,j++)
{
frac=frac+(s[i]-48)/pow(10,j); // For extracting fractional part
}
printf("\n\n%lf",sum+frac); // final answer integer part+decimal part
return 0;
}
Explanation:-
okay so what I did is:-
Since scanf() is automatically delimited by space I used gets() which is delimited by new line;
Then we know that there will be a decimal point(.) for floating number in the string, so we find the index value(say key) of the decimal point in the array.
Once we have found the decimal point we know there will only be numbers between the decimal point and the space character after the country name so now we find the index value of that space(key).
Now from that key value we again first move to the decimal point(.) character index while calculating the integer part.Calculated using ASCII value i.e. ASCII value of character Zero(0) is 48 and character Nine(9) is 57 hence subtracting 48 from every character and extracting the value.
Again from the Decimal point(.) to the next space character in the string is part of the floating number and after decimal the numbers follow the weight 10^(-1),10^(-2),10^(-3)...and so on hence the temporary variable and the power() function.Thus we, successfully calculated the fractional part also.
Finally, I just added the Integer and the fractional parts within the printf().
Try, using printf() with all the variables in each of the for loops for better understanding, kinda like dry-run.
You can parse all the values from the string using regex in c#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string[] input = {
"today average human lifespan in Western countries is approaching and exceeding 80 years.",
"1 Japan 82.6 123 19",
"2 Hong Kong 82.2 234 411",
"3 Iceland 81.8 345 26",
"4 Switzerland 81.7 456 7",
"5 Australia 81.2 567 500",
"80 Lithuania 73.0 800 2",
"194 Swaziland 39.6 142 212",
"195 133714 18.0 133 998",
"196 100110011 10.0 667 87351"
};
string pattern = #"(?'index'\d+)\s+(?'country'.*)\s+(?'float'[^ ]+)\s+(?'num1'\d+)\s+(?'num2'\d+)$";
for (int i = 1; i < input.Length; i++)
{
Match match = Regex.Match(input[i], pattern);
Console.WriteLine("index : '{0}', country : '{1}', float : '{2}', num1 : '{3}', num2 : '{4}'",
match.Groups["index"],
match.Groups["country"],
match.Groups["float"],
match.Groups["num1"],
match.Groups["num2"]
);
}
Console.ReadLine();
}
}
}
I am trying to output the statistics from my program into a file. I first create some empty strings, then amend them using sprintf, this is because I need to turn floats into chars. I then write them to a file.
I sort of works, but the output .txt file only returns 4 digits of precision regardless what I specify in sprintf.
CODE:
METRIC.RESP_TIME =(( (long int )(tval_after.tv_sec*1000000 + tval_after.tv_usec) - (long int )(tval_before.tv_sec*1000000 + tval_before.tv_usec)));
METRIC.RESP_TIME = (float) METRIC.RESP_TIME/1000000;
float ave_resp_time = METRIC.RESP_TIME/R;
float ave_through = METRIC.BYTES_RECEIVED/METRIC.RESP_TIME;
FILE *fp;
char size_str [30]; //malloc(((int)strlen(DOWNLOAD_FILE)+ (int)strlen(Q[LOCAL_QUEUE_COUNT].CHORE_NAME)))];
char rate_str [30];
char through_put_str [30];
sprintf(size_str,"TOTAL BYTES RECIEVED [B]: %5.0d ", METRIC.BYTES_RECEIVED);
sprintf(rate_str,"TOTAL TIME REQUIRED [s]: %2.8f ", ave_resp_time);
sprintf(through_put_str,"AVERAGE THROUGHPUT [B/s]: %2.8f ", ave_through);
fprintf(stdout,"%d\n",METRIC.BYTES_RECEIVED);
fp = fopen( METRICS_FILE, "w");
if(NULL == fp){
printf("Could not make metrics file: error %d ",errno);
return 0;
}
fwrite(size_str,(size_t)sizeof(size_str),1,fp);
fwrite(rate_str,sizeof(rate_str),1,fp);
fwrite(through_put_str,sizeof(through_put_str),1,fp);
fclose(fp);
return 0;
OUTPUT:
TOTAL BYTES RECIEVED [B]: 5526TOTAL TIME REQUIRED [s]: 0.001AVERAGE THROUGHPUT [B/s]: 2992
Hoping to make it look like:
TOTAL BYTES RECIEVED [B]: 55264892
TOTAL TIME REQUIRED [s]: 0.0019634
AVERAGE THROUGHPUT [B/s]: 29929054
You need an explicit new line character; fwrite() does not add one, and also you can directly use fprintf() instead of what you have.
To fix your code, do this
sprintf(size_str, "TOTAL BYTES RECIEVED [B]: %5.0d\n", METRIC.BYTES_RECEIVED);
/* ^ this will break the line */
the strcat(size_str, "\0"); is not needed.
You don't have to do all this, because you can just
fprintf(fp, "TOTAL BYTES RECIEVED [B]: %5.0d\n", METRIC.BYTES_RECEIVED);
/* ^ this will break the line */
As mentioned by #Jonathan Leffler, use well sized buffers rather than hoping that 30 is ample.
One method that has worked well is to size the buffer per the sprintf()
// char size_str [30];
// sprintf(size_str,"TOTAL BYTES RECIEVED [B]: %5.0d ", METRIC.BYTES_RECEIVED);
#define INT_MAX_PRT (sizeof(int) * CHAR_BIT/3 + 3)
const char rcv_fmt[] = "TOTAL BYTES RECEIVED [B]: %5.0d\n";
char size_str [sizeof rcv_fmt + INT_MAX_PRT];
sprintf(size_str, rcv_fmt, METRIC.BYTES_RECEIVED);
This approach is a bit more challenging with floating point as the "%f" width could be so large.
// char rate_str [30];
// sprintf(rate_str,"TOTAL TIME REQUIRED [s]: %2.8f ", ave_resp_time);
#define FLT_MAX_PRT (1 /* sign */ + FLT_MAX_10_EXP + 1)
const char *time_fmt[] = "TOTAL TIME REQUIRED [s]: %2.8f\n";
char rate_str[sizeof time_fmt + FLT_MAX_PRT + 8];
sprintf(rate_str, time_fmt, ave_resp_time);
Still, since it is possible to mistake the needed buffer size, code could also use snprintf() to minimize the harm. But in the end, a proper size buffer is needed.
Note: added '\n' to the formats.
First things first, you should get out of the habit of using sizeof on any array. This will get you into trouble faster than you realize.
Second, you seem to be doing double-duty here. There is no need to use sprintf + fwrite at all. You should just fprintf and pass you fp as the first arg.
Really strange problem with fscanf. It seems as if it can't find the file. Heres the code:
char obs_file[255];
FILE *obs_fp;
strcpy(obs_file, "/aber/dap/cetaceans/data/observers_1.txt");
obs_fp = fopen(obs_file, "r");
date_time t;
fscanf(obs_fp, "%d %d %d %d %d %d\n", &t.day, &t.mth, &t.yr, &t.hrs, &t.mns, &t.scs); //This line runs fine
obs_head.obs->time = t;
printf("%d %d %d %d %d %d\n", t.day, t.mth, t.yr, t.hrs, t.mns, t.scs);
while(feof(obs_fp) == 0) {
char id[5];
char a[7];
char b[7];
location loc;
double lng = 0.0, lat = 0.0;
fscanf(obs_fp, "%s %lf %lf", id, &lat, &lng); //Seg fault here on first run of loop
loc.lat = lat;
loc.lng = lng;
add_obs_node(make_obs_node(id, loc, t));
}
File to be read:
05 11 2014 14 53 00
AB01 52.408 -4.217
It seems like the file pointer has changed somewhere around the while statement, I would understand if I was reading over the end of file, but it fails while there are definitely lines left. Also, I know Im opening the file right, as the first fscanf runs fine.
Any ideas?
Wrong use of feof() and unlimited fscanf("%s"...
feof() reports if EOF occurred due to previous IO, not if it is about to occur.
Use instead
char id[5];
double lng = 0.0, lat = 0.0;
while(fscanf(obs_fp, "%4s%lf%lf", id, &lat, &lng) == 3) {
loc.lat = lat;
loc.lng = lng;
add_obs_node(make_obs_node(id, loc, t));
}
I suspect original code failed on the 2nd iteration. Assume the last data in the file was "AB01 52.408 -4.217\n". fscanf(obs_fp, "%s %lf %lf" would scan up to the "\n" and put "\n" back into stdin as it is not part of a double. EOF flag is not set. The use of feof() signals no EOF. So fscanf(obs_fp, "%s %lf %lf" happens again, but no data is save in id, as "%s" consume leading white-space but has not non-white-space to save. Code does not check the fscanf() return value (bad), but assumes good data in id, which may be junk. Then add_obs_node() is called with an invalid string id.
Other failure mechanisms could have occurred too - need to see more code.
Bottom line: Check fscanf() results. Limit string input.
Minor: Note that the spaces between "%d %d" are not needed, but OK to have. The final "\n" is also OK but not needed. It is not simply consuming the following '\n', but any and all following white-space.
if (6 != fscanf(obs_fp, "%d%d%d%d%d%d",
&t.day, &t.mth, &t.yr, &t.hrs, &t.mns, &t.scs)) {
Handle_BadData();
}
I have an issue with inserting time in a text file. I use the following code and i get |21,43,1,3,10,5| Wed Feb 01 20:42:32 2012 which is normal but what i WANT TO DO is place the time before the numbers for example like Wed Feb 01 20:42:32 2012 |21,43,1,3,10,5| However, i cant do so cause when i use the fprintf with ctime function before fprintf the numbers it recognizes the \n within ctime and so it changes line 1st and then printing the numbers. It goes like:
Wed Feb 01 20:42:32 2012
|21,43,1,3,10,5|
which is something that i dont want... How can i fprintf the time without swiching to the next line in the text??? Thanks in advance!
fprintf(file," |");
for (i=0;i<6;i++)
{
buffer[i]=(lucky_number=rand()%49+1); //range 1-49
for (j=0;j<i;j++)
{
if (buffer[j]==lucky_number)
i--;
}
itoa (buffer[i],draw_No,10);
fprintf(file,"%s",draw_No);
if (i!=5)
fprintf(file,",");
}
fprintf(file,"| %s",ctime(&t));
You can use a combination of strftime() and localtime() to create a custom formatted string of your timestamp:
char s[1000];
time_t t = time(NULL);
struct tm * p = localtime(&t);
strftime(s, 1000, "%A, %B %d %Y", p);
printf("%s\n", s);
The format string used by ctime is simply "%c\n".
You can use strtok() to replace \n with \0. Here's a minimal working example:
#include <stdio.h>
#include <string.h>
#include <time.h>
int main() {
char *ctime_no_newline;
time_t tm = time(NULL);
ctime_no_newline = strtok(ctime(&tm), "\n");
printf("%s - [following text]\n", ctime_no_newline);
return 0;
}
Output:
Sat Jan 2 11:58:53 2016 - [following text]
Just use %.19s :
struct timeb timebuf;
char *now;
ftime( &timebuf );
now = ctime( &timebuf.time );
/* Note that we're cutting "now" off after 19 characters to avoid the \n
that ctime() appends to the formatted time string. */
snprintf(tstring, 30, "%.19s", now); // Mon Jul 05 15:58:42
Copy the return of ctime() to a temporary string, remove the '\n' from that temporary string, then print the temporary string.
Print just the 1st 24 characters of the return from ctime() by using the (field width and) precision of the printf conversion.
in c++11 you can do it like this:
#include <iostream>
#include <chrono>
#include <iomanip>
using namespace std;
using namespace chrono;
// Prints UTC timestamp
void printTime() {
time_point<system_clock> now = system_clock::now();
time_t now_time = system_clock::to_time_t(now);
auto gmt_time = gmtime(&now_time);
auto timestamp = std::put_time(gmt_time, "%Y-%m-%d %H:%M:%S");
cout << timestamp << endl;
}
Output:
2017-06-05 00:31:49
How about:
char *p;
int len;
/* ... */
p = ctime(&t);
len = strlen(p);
fprintf(file,"| %.*s", len - 1, p);
That way it only prints the string minus the last character (i.e. the \n).
I did this after obtaining the ctime string:
#include <string.h>
...
myctime[ strlen(myctime) - 1 ] = '\0';
This just overwrites the ctime carriage return with a string termination character, effectively terminating the string with two '\0' characters instead of one. (It seems weird that ctime does that in the first place.)
Just copy 'length - 1' bytes to another string.
strncpy( newString, draw_No, strlen(draw_no) - 1 );
Simply:
c_time_string = ctime(¤t_time);
len_of_new_line = strlen(c_time_string) - 1;
c_time_string[len_of_new_line] = '\0';
What this will actually do is it replaces strlen - 1 char (new line char in this case) of ctime array with null-terminator character - it cuts out new line character from end '\n' and shorten array of 1 character.
If strlen was 25 before, after this it should be 24.