I have a problem with a program that I'm writing. It is a command line parser that parses bencode (used in torrent files). The program accepts a filename as it's command line. When I build and run the program in Microsoft Visual Studio 10.0 using the debugging Commmand Line arguments setting to input a command line the program tells me that it failed parsing.
If I open a command prompt and run the program from the command prompt with the same command line, the program works perfectly! What's going on? Is this a common problem with Visual Studio?
I used the debugger in Visual Studio to trace where the program fails and it appears that a call to the stat function ( http://msdn.microsoft.com/en-us/library/14h5k7ff.aspx ) used to get the length of the file returns an error in Visual Studio but works fine when run outside of Visual Studio.
The Code uses a Bencode parser which can be found here: http://funzix.git.sourceforge.net/git/gitweb.cgi?p=funzix/funzix;a=blob;f=bencode/bencode.c
And here is the code for the program:
#include <stdio.h>
#include "../Parse/bencode.h"
int main(int argc, char *argv[]){
if(argc != 2){
printf("Usage: whirlwind filename\n");
return 1;
}
char *buf;
long long len;
be_node *n;
//read the torrent file into a buffer and store at &buf
buf = read_file(argv[1], &len);
if(!buf){
buf = argv[1];
len = strlen(argv[1]);
}
printf("Decoding: %s\n", argv[1]);
n = be_decoden(buf, len);
if(!n){
printf("Parsing failed!\n");
return 1;
}
if(n->type != BE_DICT){
printf("This file is not a valid Bencoded Dictionary.\n");
return 1;
}
int i;
char* keyName;
for(i = 0; i < 10; i++){
keyName = n->val.d[i].key;
if(keyName == "announce"){
printf("\n\n");
}
printf("%s\n", keyName);
if(keyName == "announce"){
printf("\n\n");
}
}
return 0;
}
If you pass a relative path from Visual Studio you should be sure that it resolves correctly when your app runs inside the IDE. This problem arises because, when debugging, the current directory is usually \bin\debug.
To be on the safe side put a full pathname or read the location of your file from a configuration file.
Related
I have a cpp program that uses fopen_s to open and read a file created under the directory C:\Windows\System32\config\systemprofile\AppData\Roaming.
My program needs to be compatible with winx64 and win32.
When I run this program with a system account (run using PSTools\PSExec -i -s C:\windows\system32\cmd.exe) and the Win32 compiled version of the program, fopen_s() on any file inside "C:\Windows\System32\config\systemprofile\AppData\Roaming" returns an error code 2, even though the file is present.
However, when I run the x64 compiled version of the same program, it works fine and fopen_s() is able to find and open the same file.
I am sure there are no mistakes as far as passing a valid filename to fopen_s() and I have verified this.
I make sure that the int variable that stores the return value from fopen_s() is set to 0 every time before calling fopen_s(). I am calling fopen_s() in "r" mode.
Also, elsewhere in the same program I am able to create files under the same directory.
I am using VS2019 and cpp +11 to compile my program.
My system is running windows 10 (64-bit) on an x64 processor (Intel(R) Xeon(R) Gold 6136)
Why would a win32 application fail to read a file created under "C:\Windows\System32\config\systemprofile\AppData\Roaming" with a system account while the x64 version of the same application works fine?
Code snippet:
int FileOpenFunc(FILE ** ppFile, std::string sFilename, std::string sOpenMode)
{
int errOpen = 0;
#ifdef _WIN32
errOpen = fopen_s(ppFile, sFilename.c_str(), sOpenMode.c_str());
#else
*ppFile = fopen(sFilename.c_str(), sOpenMode.c_str());
errOpen = errno;
#endif
return errOpen;
}
void func()
{
std::string sFileName = "C:\\Windows\\System32\\config\\systemprofile\\AppData\\Roaming\\Check\\sample.txt";
int errFopenErrNo = 0;
FILE* fp = NULL;
errFopenErrNo = FileOpenFunc(&fp, sFileName, "r");
if (fp!= NULL)
{
//do something
}
else
{
//do something else
}
}
I'm using tcclib to compile and run C code on the fly in my C++ project.
I'm using the binaries provided here https://bellard.org/tcc/
I then open a vs2019 developer prompt and run both those command
lib /def:libtcc\libtcc.def /out:libtcc.lib
cl /MD examples/libtcc_test.c -I libtcc libtcc.lib
My code builds fine, I'm using this code. This code is similar to the one found in the tcclib example, which is this one : https://repo.or.cz/tinycc.git/blob/HEAD:/tests/libtcc_test.c (this is another repo, but it's the same code.
The code I run is this one. This is inside an extern "C" {}.
int tcc_stuff(int argc, const char** argv) {
TCCState* s;
int i;
int (*func)(int);
s = tcc_new();
if (!s) {
fprintf(stderr, "Could not create tcc state\n");
exit(1);
}
/* if tcclib.h and libtcc1.a are not installed, where can we find them */
for (i = 1; i < argc; ++i) {
const char* a = argv[i];
if (a[0] == '-') {
if (a[1] == 'B')
tcc_set_lib_path(s, a + 2);
else if (a[1] == 'I')
tcc_add_include_path(s, a + 2);
else if (a[1] == 'L')
tcc_add_library_path(s, a + 2);
}
}
/* MUST BE CALLED before any compilation */
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
{
const char* other_file = ReadFile2(argv[1]);
if (other_file == NULL)
{
printf("invalid filename %s\n", argv[1]);
return 1;
}
if (tcc_compile_string(s, other_file) == -1)
return 1;
}
/* as a test, we add symbols that the compiled program can use.
You may also open a dll with tcc_add_dll() and use symbols from that */
tcc_add_symbol(s, "add", add);
tcc_add_symbol(s, "hello", hello);
/* relocate the code */
if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)
return 1;
/* get entry symbol */
func = (int(*)(int))tcc_get_symbol(s, "foo");
if (!func)
return 1;
/* run the code */
msg(func(32));
//msg(func2(4));
/* delete the state */
tcc_delete(s);
return 0;
}
When running my code, TCC had the error
tcc: error: library 'libtcc1-32.a' not found
I fixed it by placing this file in the lib/ directory next to my .exe
I also copied the include/ folder to include stdio.h etc.
My question is: why does it need this file in a lib/ folder, instead of the provided tcclib.dll file? Is it possible to "ship" certain headers like stdio.h?
The question has no answer but 360 views, so I thought I'd reply.
The library doesn't necessarily need to be in that folder. To quote the author's command line docs, which still apply to the library,
-Ldir
Specify an additional static library path for the -l option. The default library paths are /usr/local/lib, /usr/lib and /lib.
I inferred your program to be a modified main() of libtcc_test.c & fixed it to the point of functioning. Then I used VS2022 to retrace your steps, put the .a files into the same folder as my new tests_libtcc_test.exe, then I ran this:
tests_libtcc_test c:/lang/tcc/examples/fib.c -Ic:/lang/tcc/include -L.
The library issue appears if I don't -L anything, and disappears if I include at least the ".".
And of course, you can drop the include folder into your redistributable and include it by default right from the code.
Because the tcc DLL is just another interface to the same compiler, it needs the same things tcc.exe would to build an executable; in this case, it needs the same libraries.
I have a problem with reading lines from a .txt file in C++.
The code is compiled with gmake on a FreeBSD environment.
So here is my code
int main(int argc, char **argv)
{
std::string temp_value_line;
std::string filename = "values.txt";
std::ifstream open_file(filename.c_str());
if (!open_file.is_open()) {
sys_err("Failed to load values from values.txt");
return 0;
}
int counter = 0;
while (!open_file.eof())
{
open_file >> temp_value_line;
str_to_number(common_value[counter], temp_value_line.c_str());
counter++;
}
sys_log(0, "values loaded succsefully");
open_file.close();
}
After building and running the application, there is the specified error message in my error log, so the file is not opened.
I already checked if there is a permissions or naming problem like "values.txt.txt" but everything seems to be okay. I am able to read/modify the file via console editor.
Thanks in advance.
I have some code that is executed from the command line. It takes 3 parameters:
"example.txt" 3 s
I want to be able to run this program from inside of my Eclipse IDE instead of running it from the command line but I do not know how to assign the parameters without creating bugs int the program.
Here is the main method below:
int main(int argc, char **argv) {
if (argc != 4) {
fprintf(stderr, "Usage: %s <input file> <num clusters> "
"<linkage type>\n", argv[0]);
exit(1);
} else {
item_t *items = NULL;
int num_items = process_input(&items, argv[1]);
set_linkage(argv[3][0]);
if (num_items) {
cluster_t *cluster = agglomerate(num_items, items);
free(items);
if (cluster) {
fprintf(stdout, "CLUSTER HIERARCHY\n"
"--------------------\n");
print_cluster(cluster);
int k = atoi(argv[2]);
fprintf(stdout, "\n\n%d CLUSTERS\n"
"--------------------\n", k);
get_k_clusters(cluster, k);
free_cluster(cluster);
}
}
}
return 0;
}
I am using c++ and eclipse IDE.
You basically need to create a debug/run configuration for said project. Go to Run->Debug Configurations, select C/C++ Application, then create a new configuration. After that, you have to specify some information, like the application, the eclipse project, and your program`s arguments, on the Arguments Tab.
Screenshots from here are a bit old, but should give you the idea.
After that, hit Debug or Run, and Eclipse shoud start your program with the given parameters.
I am using Microsoft Visual Studio 2010, and i am working on open source Clamav, my code is given below which is generating an error
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <clamav.h>
int main(int argc, char **argv)
{
int fd, ret;
unsigned long int size = 0;
unsigned int sigs = 0;
long double mb;
const char *virname;
struct cl_engine *engine;
if(argc != 2) {
printf("Usage: %s file\n", argv[0]);
return 2;
}
if((fd = open(argv[1], O_RDONLY)) == -1) {
printf("Can't open file %s\n", argv[1]);
return 2;
}
if((ret = cl_init(CL_INIT_DEFAULT)) != CL_SUCCESS) {
printf("Can't initialize libclamav: %s\n", cl_strerror(ret));
return 2;
}
if(!(engine = cl_engine_new())) {
printf("Can't create new engine\n");
return 2;
}
/* load all available databases from default directory */
if((ret = cl_load(cl_retdbdir(), engine, &sigs, CL_DB_STDOPT)) != CL_SUCCESS) {
printf("cl_load: %s\n", cl_strerror(ret));
close(fd);
cl_engine_free(engine);
return 2;
}
printf("Loaded %u signatures.\n", sigs);
/* build engine */
if((ret = cl_engine_compile(engine)) != CL_SUCCESS) {
printf("Database initialization error: %s\n", cl_strerror(ret));;
cl_engine_free(engine);
close(fd);
return 2;
}
/* scan file descriptor */
if((ret = cl_scandesc(fd, &virname, &size, engine, CL_SCAN_STDOPT)) == CL_VIRUS) {
printf("Virus detected: %s\n", virname);
} else {
if(ret == CL_CLEAN) {
printf("No virus detected.\n");
} else {
printf("Error: %s\n", cl_strerror(ret));
cl_engine_free(engine);
close(fd);
return 2;
}
}
close(fd);
/* free memory */
cl_engine_free(engine);
/* calculate size of scanned data */
mb = size * (CL_COUNT_PRECISION / 1024) / 1024.0;
printf("Data scanned: %2.2Lf MB\n", mb);
return ret == CL_VIRUS ? 1 : 0;
}
the following error is generated
LINK : fatal error LNK1181: cannot open input file 'libclamav.lib'
kindly guide me
You get an LNK1181 error in Visual Studio when the .lib or .obj files that are specified during linking are not found in the current directory, any of the directories that are specified by the LIBPATH linker option, or any of the directories that are specified in the LIB environment variable.
You may add the directory that contains libclamav.lib library file to the LIBPATH to resolve the problem (this instructions may vary a bit depending on your Visual Studio version):
In Solution Explorer, right-click the project, and then click Properties.
In the Property Pages dialog box, expand Linker, and then click General.
In the Additional Library Directories field, specify the path where libclamav.lib resides.
The error can also happen when the LIBPATH contains spaces. If that's the case, move the library to a path without spaces or put quotation marks around the path.
You can also fix it by specifying the library path in DOS "8.3" format.
To get the 8.3 form, do (at the command line):
DIR /AD /X
recursively through every level of the directories.