unable to edit the second line of the file in cpp - file

I want to edit the username and password according to userinput. I have a file exampless.txt whixh has default username and password values. I want to replace the values of username and password according to user input. I'm able to replace the username value. But password values doesnt get changed.
Please help.
My code is as below:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
int main()
{
std::wstring y;
std::wstring username;
std::wstring password;
std::cout<<"enter the username:";
std::wcin>>username;
std::cout<<"enter the password:";
std::wcin>>password;
std::wstring x=L"username";
std::wstring a=L"password";
std::wfstream fp("/home/aricent/Documents/exampless.txt",std::ios::in | std::ios::out );
while(!fp.eof()) {
std::getline(fp, y);
if (y.find(x, 0) != std::string::npos) {
std::wstring z=y.substr(y.find(L"-") + 1) ;
fp.seekg( 0, std::ios::beg );
fp<<y.replace(x.length()+1, z.length(), username)<<"\n";
fp.clear();
fp.seekg( 0, std::ios::beg );
}
fp.seekg(0,std::ios::beg);
std::getline(fp, y);
if (y.find(a, 0) != std::string::npos) {
std::wstring b=y.substr(y.find(L"-") + 1) ;
fp<<y.replace(a.length()+1, b.length(), password <<std::endl;
fp.clear();
}
}
fp.close();
}
my exampless.txt file contains:
username-aaa
password-bbb

There are many reasons why your code doesn't work. Some have to do with the way you intend to do this. Some have to do with the way you actually implemented your idea.
So I suggest you simplify the code in the following way.
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
int main() {
std::wstring username;
std::wstring password;
std::cout<<"enter the username:";
std::wcin>>username;
std::cout<<"enter the password:";
std::wcin>>password;
std::wfstream fp("/home/aricent/Documents/exampless.txt",std::ios::in | std::ios::out );
if(!fp) { /* Failed to open file. do something */ }
<here you can check whether the file is already properly formatted>
if(!(fp << "username-" << username << "\npassword-" << password << "\n") {
//writing failed. Do something to handle this error (like throwing an exception)
}
fp.close();
}
So instead of reading the file contents, modifying it and writing it back to the file you can simply overwrite it with whatever you want it to contain.
This avoids (and fixes in this case) a lot of problems.
Also, your code should check for any exceptional states and handle them properly (like failing to open the file).
In your code you also check for whether the file is properly formatted (e.g. are the username and password lines already there) before writing to it. The above changes make this step redundant but if you still want this check to be done you can put it in between the two if's.
Finally I want to clear up a misconception. std::fstream maintains two separate positions into the filestream. One for reading and one for writing. To change these positions it has two methods seekp(pos) and seekg(pos). seekp(pos) changes at what position in the filestream any write operation (like operator << and put()) starts writing (the p stands for put I guess). seekg(pos) changes at what position in the filestream any read operation (like operator >> and get()) starts writing (the g stands for get).
Reading from a stream only changes the reading position but not the writing position and vice versa.

Related

How to get Windows username and use it in a system function [duplicate]

I want to access the user name in the Windows using C programming and use that name to create the path to the particular file like "c:\users\john\Roaming.....and so on". So for every system user name e.g "john" is different. Help me to find the user name at run time.
#include <stdio.h>
int main(void)
{
printf("%s\n", getenv("USERPROFILE")); // Print user's home directory.
return 0;
}
To get the user name instead of the home path replace USERPROFILE with USERNAME.
What you are looking for, here, is probably more SHGetKnownFolderPath. The function lets you find per-user special folders. This is preferred to querying usernames because the home folder may not have the same name as the user.
WSTR* location;
HRESULT hr = SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &location);
if (SUCCEEDED(hr))
{
// location contains the folder path
// call CoTaskMemFree to free up the memory once you're done with it
CoTaskMemFree(location);
}
The list of so-called known folders is available here.
The function to get user name on windows is GetUserName
This answer, probably, will help you too.
you could use the following code to get the Username.
#include <stdlib.h>
void main(void)
{
//following gets the appdata folder
char szAppData[1024];
char * szBufer = 0;
szBufer = getenv ("APPDATA");
if (szBufer != NULL)
{
strcpy(szBufer , szAppData);
}
//following code gets the user name
char szOSUserName[1024];
szBufer = getenv ("USERNAME");
if (szBufer != NULL)
{
strcpy(szBufer , szOSUserName);
}
}
You can get the name of the current user with GetUserName:
#include <Windows.h>
#include <Lmcons.h>
#include <stdio.h>
int main()
{
char name[UNLEN + 1];
DWORD cch = UNLEN + 1;
if (GetUserName(name, &cch))
{
char cmd[100 + UNLEN + 1];
sprintf(cmd, "echo The username is \"%s\"", name); // Silly demo command
system(cmd);
}
return 0;
}
Use GetUserNameEx if you want the name in a specific format.
If you need to get the path to a special folder like "My Documents" or "Desktop" you should use the special folder functions like SHGetFolderPath or SHGetKnownFolderPath.
%USERNAME% will give you the username, but a better solution is to store it on %USERPROFILE%\\Desktop\\key.txt to at least make it OS-independent.
And an even better solution would be not to store private information on the users' desktops. Or anywhere.

C++ taking string from user and adding it to the end of a file

I want to take a sentence from a user and add it to the end of a file.
The sentence will contain a name, a height and a weight. It's for calculating BMIs.
[name] [height] [weight]
So, I do this:
void write(){
fstream writing ("data.txt", ios::in | ios::out | ios::ate); // write to
//end of file because file has data in it
if (writing.is_open())
{
string input;
cout << "Enter some data: name height weight\n";
char space_checker = _getch(); // using _getch() with <conio.h>
while (space_chcker != 13) { // char value of enter is 13
getline(cin,input);
writing << user_input;
check = _getch();
}
}
When the user goes to type something in, it ignores the first two keystrokes - they don't register. What is going wrong here?
The first and second instance of _getch() is causing the keystroke problem, anyway to fix this?

Ruby C extension rb_str_new2 seems to return false

I cannot post my actual code due to work copyright, so I will try to show my problem with simple example code.
I have a C extension whose simplified version looks like:
#include <ruby.h>
#include <termios.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
VALUE test(VALUE self, VALUE string);
void Init_module_name() {
module_name = rb_define_module("Modulename");
c_modulename = rb_define_class_under(modulename, "Class", rb_cObject);
rb_define_method(c_modulename, "test", test, 1);
e_ModuleNameError = rb_define_class_under(modulename, "Error", rb_eStandardError);
}
VALUE test(VALUE self, VALUE string) {
char *c_string = StringValueCStr(string);
int fd = open(c_string, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd == -1) {
rb_raise(e_ModuleNameError, "Failed to open file");
}
if (!isatty(fd)) {
rb_raise(e_ModuleNameError, "File is not a tty");
}
struct termios config;
int termios_ret = init_termios(config, fd)
if (termios_ret != OK) { // OK defined by enum in modulename's header
close(fd);
rb_raise(e_ModuleNameError, "Termios init failed.");
}
int success = write(fd, "I'm a string", str_length);
if (success < str_length) {
close(fd);
rb_raise(e_ModuleNameError, "Failed to write to file.");
}
close(fd);
return rb_str_new2("Success");
}
Then, the ruby code that requires this looks like:
require 'modulename'
class ModuleName
attr_acessor :file
def initialize(file)
#file = file
#object = Modulename::Class.new
end
def test
#object.test #file
end
end
Which is then called in my production project like:
require "modulename_ruby_file"
x = ModuleName "/dev/pts/1"
x.test
Here is the interesting thing. When I run this code in production, the return value from x.test above is false (As in literally the value false, not a string). Also, the write to the file never happens. However, if I do it in some simplified test code it returns the string "Success" just like expected and the write is indeed completed.
Does anyone know of any situation that would cause this function not to execute the write, and return false? I already tried putting a rescue around it in case it was throwing one of the rb_raises, but it doesn't appear to be.
Me and 3 other members of my team have looked at this all afternoon and have not found an answer.
Finally figured this out, and it was very similar to what #NeilSlater was saying in the comments on the question.
We added a TON of debugging to the C code and had it write to a log file, and figured out that the C function (test in my example) was literally never being called. So, we looked at the symbol table for the .so and the assembly code gcc was generating and both looked fine. Finally we just said, "Let's change the name of the function and see if that helps" and... it worked. The actual function was named logout, and changing it to project_name_logout worked, so apparently there was some kind of namespace collision. So, much like #NeilSlater said, it had something to do with the environment!
So, for anyone else finding this on google: Add a "namespace" to your C code by prefixing all functions with your project name and you should be able to avoid this issue. [One of the other members mentioned, after the fact, that this was a good practice in C anyway.]
Note: We did not take the time to track down what was colliding with logout.

Get line number of called function C

Is there a way to get the line number a function was called on in C without doing anything like below?
The define can make it tedious after a while, having to use DP instead of { like usual, and hard to read; but the adding LINE as the first parameter to every function is just something I'm not willing to do.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#define println(x,...) printf(x,##__VA_ARGS__);printf("\n");
/*
*I would like to be able to replace __LINE__ with the line
*each function was called on, or replace my DP define completely...
*/
#ifdef _DEBUG_
#define DP { println("%s:%d\t%s()",__FILE__,__LINE__,__FUNCTION__);
#else
#define DP {
#endif
void calledFunc()
DP
println("something something something");
}
void cFunc(int line)
{
println("%s:%d\t%s()",__FILE__,line,__FUNCTION__);
}
int main()
DP
calledFunc();
/* ...and I don't want to have to do this all the time either*/
cFunc(__LINE__);
}
There is a good substitute for printing the line file name/number. It is called "LocationID" or LID.
LID is a number that is generated out the project wide counter. The latest value of the counter should be stored in the source file and checked in/out of the source control system like any other source file. The value of the counter can be scrambled. This forces its proper use. You use it like:
#ifdef _DEBUG_
#define DP(x, msg) println("%d: %s", x, msg);
#endif
and in your source:
DP (3517, "Here we are.")
Advantage of the LIDs are:
They are stable against modification of the source file, including renaming of the file/function.
They are easy to find in the sources.
Log file is much more compact and clear than with the file name and the function name.
I used this several times and it proved to be good. Generation and distribution of LID values among developers is an overhead, but the result is 10 times worth the price of this effort.

Create temporary file in C, MS Windows system

Basically, i have a program that is given a 4 meg compressed file, it has to decode this file into uncompressed ~ 100 meg, then compress it back into ~4 meg file. I need to store this intermediate 100 meg file somewhere on the drive (dont want to keep it in memory).
Program is written in C and will be executed on MS Windows 7. At the moment of uncompressing, no guaranteed folder (with write access) is given to the program (folder with source file might be read only and folder with target file might be not yet specified).
This has proven to be not an easy task:
1) I have read about a C function that creates a temp file that will disappear when closed or program is terminated. However, from what i understand it tries to make the file on disk C, in root directory, so this will obviously fail if user has no rights for that (which normal user doesnt)
2) I had an idea to use environmental/system variable TEMP and create a file there, BUT looking on a random Win7 PC which wasnt tweaked, i see that this variable points to c:/windows/temp, and that folder has specific rights for "users" - that is, they have rights to read, execute, create and write files, but not to delete them, check their attributes, etc. This means, i assume, that if program is ran with user privilleges, it will be able to make a file but not able to delete it, so the only way to "delete" it would be to open the file for writing and then close it, making it a 0 length file. This is also not desired, and i dont know how to query for system variables from C
3) So, basically, only idea i have right now is to make a function to open file that:
tries to create a temp file in the output dir, if possible
if failed, tries to create a temp file in input dir
if failed, tries to create a temp file in TEMP dir from system variable
if failed, tries to create a temp file in TMP dir from system variable
and a delete function that:
tries to remove() the file (by its name that is stored somewhere)
if failed, it tries to open the file for write, and close it, so it becomes a 0 byte file
Are there better ideas?
Any help is appreciated, thanks!
PS: Program must not use any external libraries like MFC or something, only built-in standart C functions
GetTempPath
Retrieves the path of the directory designated for temporary files.
GetTempFileName
Creates a name for a temporary file. If a unique file name is
generated, an empty file is created and the handle to it is released;
otherwise, only a file name is generated.
These two provide you easy way to obtain a location and name for a temporary file.
UPD: Code sample on MSDN: Creating and Using a Temporary File.
#include <windows.h>
#include <iostream>
#include <chrono>
#include <string>
#include <cstdio>
#include <chrono>
using namespace std;
int FileExists(string& filepath)
{
DWORD dwAttrib = GetFileAttributes(filepath.c_str());
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
int GetTemporaryFilePath(
string filePrefix,
string fileExt,
string& TmpFilePath /*return*/)
{
if (fileExt[0] == '.')
fileExt.erase(0,1);
char TempPath[MAX_PATH] = { 0 };
if (!GetTempPath(MAX_PATH, TempPath))
return -1;
uint16_t tickint = 0;
while(1) {
const int nowlen = 17; char nowstr[nowlen];
const int ticklen = 5; char tickstr[ticklen];
// Milliseconds since 1970
auto ms = chrono::duration_cast<chrono::milliseconds>(
chrono::system_clock::now().time_since_epoch()
);
__int64 nowint = ms.count();
snprintf(nowstr, nowlen, "%016" "I64" "x", nowint);
snprintf(tickstr, ticklen, "%04x", tickint);
TmpFilePath = string(TempPath)
+ filePrefix
+ "." + string(nowstr)
+ "." + string(tickstr)
+ "." + fileExt;
if (!FileExists(TmpFilePath)) {
//Touch File
FILE* w = fopen(TmpFilePath.c_str(), "w");
fclose(w);
break;
}
tickint++;
}
return 0;
}
int main()
{
string TmpFilePath;
GetTemporaryFilePath("MyFile", ".txt", TmpFilePath);
cout << "TmpFilePath: " << TmpFilePath << endl;
return 0;
}

Resources